Update Clang for rebase to r212749.

This also fixes a small issue with arm_neon.h not being generated always.

Includes a cherry-pick of:
r213450 - fixes mac-specific header issue
r213126 - removes a default -Bsymbolic on Android

Change-Id: I2a790a0f5d3b2aab11de596fc3a74e7cbc99081d
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2d7bb6f..28f4e3f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -156,11 +156,14 @@
   endif()
 
   set( CLANG_BUILT_STANDALONE 1 )
+  set(BACKEND_PACKAGE_STRING "LLVM ${LLVM_PACKAGE_VERSION}")
+else()
+  set(BACKEND_PACKAGE_STRING "${PACKAGE_STRING}")
+endif()
 
-  find_package(LibXml2)
-  if (LIBXML2_FOUND)
-    set(CLANG_HAVE_LIBXML 1)
-  endif ()
+find_package(LibXml2)
+if (LIBXML2_FOUND)
+  set(CLANG_HAVE_LIBXML 1)
 endif()
 
 set(CLANG_RESOURCE_DIR "" CACHE STRING
diff --git a/README.txt b/README.txt
index 44ce723..474c67c 100644
--- a/README.txt
+++ b/README.txt
@@ -8,7 +8,7 @@
 
 Unlike many other compiler frontends, Clang is useful for a number of things
 beyond just compiling code: we intend for Clang to be host to a number of
-different source level tools.  One example of this is the Clang Static Analyzer.
+different source-level tools.  One example of this is the Clang Static Analyzer.
 
 If you're interested in more (including how to build Clang) it is best to read
 the relevant web sites.  Here are some pointers:
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index b673f4b..517b3c1 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -272,7 +272,7 @@
             return False
         if other.file is None and self.start.file is None:
             pass
-        elif ( self.start.file.name != other.file.name or 
+        elif ( self.start.file.name != other.file.name or
                other.file.name != self.end.file.name):
             # same file name
             return False
@@ -748,7 +748,7 @@
 # that has not yet been resolved to a specific function or function template.
 CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
 
-# A reference to a variable that occurs in some non-expression 
+# A reference to a variable that occurs in some non-expression
 # context, e.g., a C++ lambda capture list.
 CursorKind.VARIABLE_REF = CursorKind(50)
 
@@ -937,7 +937,7 @@
 
 # Represents a C++ lambda expression that produces a local function
 # object.
-# 
+#
 #  \code
 #  void abssort(float *x, unsigned N) {
 #    std::sort(x, x + N,
@@ -947,7 +947,7 @@
 #  }
 #  \endcode
 CursorKind.LAMBDA_EXPR = CursorKind(144)
-  
+
 # Objective-c Boolean Literal.
 CursorKind.OBJ_BOOL_LITERAL_EXPR = CursorKind(145)
 
@@ -1082,6 +1082,10 @@
 CursorKind.PURE_ATTR = CursorKind(409)
 CursorKind.CONST_ATTR = CursorKind(410)
 CursorKind.NODUPLICATE_ATTR = CursorKind(411)
+CursorKind.CUDACONSTANT_ATTR = CursorKind(412)
+CursorKind.CUDADEVICE_ATTR = CursorKind(413)
+CursorKind.CUDAGLOBAL_ATTR = CursorKind(414)
+CursorKind.CUDAHOST_ATTR = CursorKind(415)
 
 ###
 # Preprocessing
@@ -1162,10 +1166,6 @@
     @property
     def spelling(self):
         """Return the spelling of the entity pointed at by the cursor."""
-        if not self.kind.is_declaration():
-            # FIXME: clang_getCursorSpelling should be fixed to not assert on
-            # this, for consistency with clang_getCursorUSR.
-            return None
         if not hasattr(self, '_spelling'):
             self._spelling = conf.lib.clang_getCursorSpelling(self)
 
@@ -1345,7 +1345,7 @@
     @property
     def referenced(self):
         """
-        For a cursor that is a reference, returns a cursor 
+        For a cursor that is a reference, returns a cursor
         representing the entity that it references.
         """
         if not hasattr(self, '_referenced'):
@@ -1357,7 +1357,7 @@
     def brief_comment(self):
         """Returns the brief comment text associated with that Cursor"""
         return conf.lib.clang_Cursor_getBriefCommentText(self)
-    
+
     @property
     def raw_comment(self):
         """Returns the raw comment text associated with that Cursor"""
@@ -1387,6 +1387,16 @@
             children)
         return iter(children)
 
+    def walk_preorder(self):
+        """Depth-first preorder walk over the cursor and its descendants.
+
+        Yields cursors.
+        """
+        yield self
+        for child in self.get_children():
+            for descendant in child.walk_preorder():
+                yield descendant
+
     def get_tokens(self):
         """Obtain Token instances formulating that compose this Cursor.
 
diff --git a/bindings/python/tests/cindex/util.py b/bindings/python/tests/cindex/util.py
index 8614b02..c53ba7c 100644
--- a/bindings/python/tests/cindex/util.py
+++ b/bindings/python/tests/cindex/util.py
@@ -39,52 +39,34 @@
 
     If the cursor is not found, None is returned.
     """
-    children = []
-    if isinstance(source, Cursor):
-        children = source.get_children()
-    else:
-        # Assume TU
-        children = source.cursor.get_children()
+    # Convenience for calling on a TU.
+    root_cursor = source if isinstance(source, Cursor) else source.cursor
 
-    for cursor in children:
+    for cursor in root_cursor.walk_preorder():
         if cursor.spelling == spelling:
             return cursor
 
-        # Recurse into children.
-        result = get_cursor(cursor, spelling)
-        if result is not None:
-            return result
-
     return None
- 
+
 def get_cursors(source, spelling):
     """Obtain all cursors from a source object with a specific spelling.
 
-    This provides a convenient search mechanism to find all cursors with specific
-    spelling within a source. The first argument can be either a
+    This provides a convenient search mechanism to find all cursors with
+    specific spelling within a source. The first argument can be either a
     TranslationUnit or Cursor instance.
 
     If no cursors are found, an empty list is returned.
     """
-    cursors = []
-    children = []
-    if isinstance(source, Cursor):
-        children = source.get_children()
-    else:
-        # Assume TU
-        children = source.cursor.get_children()
+    # Convenience for calling on a TU.
+    root_cursor = source if isinstance(source, Cursor) else source.cursor
 
-    for cursor in children:
+    cursors = []
+    for cursor in root_cursor.walk_preorder():
         if cursor.spelling == spelling:
             cursors.append(cursor)
 
-        # Recurse into children.
-        cursors.extend(get_cursors(cursor, spelling))
-
     return cursors
 
-    
-    
 
 __all__ = [
     'get_cursor',
diff --git a/clang-tblgen-rules.mk b/clang-tblgen-rules.mk
index 0fa1735..cdd9f72 100644
--- a/clang-tblgen-rules.mk
+++ b/clang-tblgen-rules.mk
@@ -224,14 +224,6 @@
 	$(call transform-host-td-to-out,opt-parser-defs)
 endif
 
-ifneq ($(findstring CC1AsOptions.inc,$(TBLGEN_TABLES)),)
-LOCAL_GENERATED_SOURCES += $(intermediates)/include/clang/Driver/CC1AsOptions.inc
-$(intermediates)/include/clang/Driver/CC1AsOptions.inc: TBLGEN_LOCAL_MODULE := $(LOCAL_MODULE)
-$(intermediates)/include/clang/Driver/CC1AsOptions.inc: $(CLANG_ROOT_PATH)/include/clang/Driver/CC1AsOptions.td $(LLVM_ROOT_PATH)/include/llvm/Option/OptParser.td \
-    | $(CLANG_TBLGEN) $(LLVM_TBLGEN)
-	$(call transform-host-td-to-out,opt-parser-defs)
-endif
-
 LOCAL_C_INCLUDES += $(intermediates)/include
 
 endif
diff --git a/docs/AttributeReference.rst b/docs/AttributeReference.rst
index 34a812d..c12f6d8 100644
--- a/docs/AttributeReference.rst
+++ b/docs/AttributeReference.rst
@@ -219,14 +219,14 @@
 The ``carries_dependency`` attribute specifies dependency propagation into and
 out of functions.
 
-When specified on a function or Objective-C method, the ``carries_depedency``
+When specified on a function or Objective-C method, the ``carries_dependency``
 attribute means that the return value carries a dependency out of the function, 
 so that the implementation need not constrain ordering upon return from that
 function. Implementations of the function and its caller may choose to preserve
 dependencies instead of emitting memory ordering instructions such as fences.
 
 Note, this attribute does not change the meaning of the program, but may result
-in generatation of more efficient code.
+in generation of more efficient code.
 
 
 enable_if
@@ -312,6 +312,18 @@
 Query for this feature with ``__has_attribute(enable_if)``.
 
 
+flatten (gnu::flatten)
+----------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``flatten`` attribute causes calls within the attributed function to
+be inlined unless it is impossible to do so, for example if the body of the
+callee is unavailable or if the callee has the ``noinline`` attribute.
+
+
 format (gnu::format)
 --------------------
 .. csv-table:: Supported Syntaxes
@@ -467,6 +479,18 @@
 tool to avoid false positives and provide meaningful stack traces.
 
 
+no_split_stack (gnu::no_split_stack)
+------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``no_split_stack`` attribute disables the emission of the split stack
+preamble for a particular function. It has no effect if ``-fsplit-stack``
+is not specified.
+
+
 objc_method_family
 ------------------
 .. csv-table:: Supported Syntaxes
@@ -545,6 +569,24 @@
                       ^
 
 
+optnone (clang::optnone)
+------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``optnone`` attribute suppresses essentially all optimizations
+on a function or method, regardless of the optimization level applied to
+the compilation unit as a whole.  This is particularly useful when you
+need to debug a particular function, but it is infeasible to build the
+entire application without optimization.  Avoiding optimization on the
+specified function can improve the quality of the debugging information
+for that function.
+
+This attribute is incompatible with the ``always_inline`` attribute.
+
+
 overloadable
 ------------
 .. csv-table:: Supported Syntaxes
@@ -632,6 +674,18 @@
 Query for this feature with ``__has_extension(attribute_overloadable)``.
 
 
+pcs (gnu::pcs)
+--------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+On ARM targets, this can attribute can be used to select calling conventions,
+similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
+"aapcs-vfp".
+
+
 release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability)
 -----------------------------------------------------------------------------------------------------------
 .. csv-table:: Supported Syntaxes
@@ -659,6 +713,17 @@
 ===================
 
 
+section (gnu::section, __declspec(allocate))
+--------------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","X",""
+
+The ``section`` attribute allows you to specify a specific section a
+global variable or function should be in after translation.
+
+
 tls_model (gnu::tls_model)
 --------------------------
 .. csv-table:: Supported Syntaxes
@@ -677,6 +742,26 @@
 TLS models are mutually exclusive.
 
 
+thread
+------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "","","X",""
+
+The ``__declspec(thread)`` attribute declares a variable with thread local
+storage.  It is available under the ``-fms-extensions`` flag for MSVC
+compatibility.  Documentation for the Visual C++ attribute is available on MSDN_.
+
+.. _MSDN: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
+
+In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the
+GNU ``__thread`` keyword.  The variable must not have a destructor and must have
+a constant initializer, if any.  The attribute only applies to variables
+declared with static storage duration, such as globals, class static data
+members, and static locals.
+
+
 Type Attributes
 ===============
 
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index 0483bd7..910192b 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -211,9 +211,12 @@
   the parentheses of a function call with that name. If there is no name,
   a zero-length name is assumed.
 
-**DerivePointerBinding** (``bool``)
-  If ``true``, analyze the formatted file for the most common binding
-  and use ``PointerBindsToType`` only as fallback.
+**DerivePointerAlignment** (``bool``)
+  If ``true``, analyze the formatted file for the most common
+  alignment of & and *. ``PointerAlignment`` is then used only as fallback.
+
+**DisableFormat** (``bool``)
+  Disables formatting at all.
 
 **ExperimentalAutoDetectBinPacking** (``bool``)
   If ``true``, clang-format detects whether function calls and
@@ -245,13 +248,13 @@
   When ``false``, use the same indentation level as for the switch statement.
   Switch statement body is always indented one level more than case labels.
 
-**IndentFunctionDeclarationAfterType** (``bool``)
-  If ``true``, indent when breaking function declarations which
-  are not also definitions after the type.
-
 **IndentWidth** (``unsigned``)
   The number of columns to use for indentation.
 
+**IndentWrappedFunctionNames** (``bool``)
+  Indent if a function definition or declaration is wrapped after the
+  type.
+
 **KeepEmptyLinesAtTheStartOfBlocks** (``bool``)
   If true, empty lines at the start of blocks are kept.
 
@@ -314,8 +317,18 @@
   Penalty for putting the return type of a function onto its own
   line.
 
-**PointerBindsToType** (``bool``)
-  Set whether & and * bind to the type as opposed to the variable.
+**PointerAlignment** (``PointerAlignmentStyle``)
+  Pointer and reference alignment style.
+
+  Possible values:
+
+  * ``PAS_Left`` (in configuration: ``Left``)
+    Align pointer to the left.
+  * ``PAS_Right`` (in configuration: ``Right``)
+    Align pointer to the right.
+  * ``PAS_Middle`` (in configuration: ``Middle``)
+    Align pointer in the middle.
+
 
 **SpaceBeforeAssignmentOperators** (``bool``)
   If ``false``, spaces will be removed before assignment operators.
diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst
index 5830a7e..8e047db 100644
--- a/docs/InternalsManual.rst
+++ b/docs/InternalsManual.rst
@@ -1852,13 +1852,14 @@
    * Make sure that ``children()`` visits all of the subexpressions.  This is
      important for a number of features (e.g., IDE support, C++ variadic
      templates).  If you have sub-types, you'll also need to visit those
-     sub-types in the ``RecursiveASTVisitor``.
-   * Add printing support (``StmtPrinter.cpp``) and dumping support
-     (``StmtDumper.cpp``) for your expression.
+     sub-types in ``RecursiveASTVisitor`` and ``DataRecursiveASTVisitor``.
+   * Add printing support (``StmtPrinter.cpp``) for your expression.
    * Add profiling support (``StmtProfile.cpp``) for your AST node, noting the
      distinguishing (non-source location) characteristics of an instance of
      your expression.  Omitting this step will lead to hard-to-diagnose
      failures regarding matching of template declarations.
+   * Add serialization support (``ASTReaderStmt.cpp``, ``ASTWriterStmt.cpp``)
+     for your AST node.
 
 #. Teach semantic analysis to build your AST node.  At this point, you can wire
    up your ``Sema::BuildXXX`` function to actually create your AST.  A few
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index 5e957cb..ad7821a 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -1446,6 +1446,24 @@
     return __builtin_addressof(value);
   }
 
+``__builtin_operator_new`` and ``__builtin_operator_delete``
+------------------------------------------------------------
+
+``__builtin_operator_new`` allocates memory just like a non-placement non-class
+*new-expression*. This is exactly like directly calling the normal
+non-placement ``::operator new``, except that it allows certain optimizations
+that the C++ standard does not permit for a direct function call to
+``::operator new`` (in particular, removing ``new`` / ``delete`` pairs and
+merging allocations).
+
+Likewise, ``__builtin_operator_delete`` deallocates memory just like a
+non-class *delete-expression*, and is exactly like directly calling the normal
+``::operator delete``, except that it permits optimizations. Only the unsized
+form of ``__builtin_operator_delete`` is currently available.
+
+These builtins are intended for use in the implementation of ``std::allocator``
+and other similar allocation libraries, and are only available in C++.
+
 Multiprecision Arithmetic Builtins
 ----------------------------------
 
@@ -1562,7 +1580,9 @@
 .. code-block:: c
 
   T __builtin_arm_ldrex(const volatile T *addr);
+  T __builtin_arm_ldaex(const volatile T *addr);
   int __builtin_arm_strex(T val, volatile T *addr);
+  int __builtin_arm_stlex(T val, volatile T *addr);
   void __builtin_arm_clrex(void);
 
 The types ``T`` currently supported are:
@@ -1571,11 +1591,11 @@
 * Pointer types.
 
 Note that the compiler does not guarantee it will not insert stores which clear
-the exclusive monitor in between an ``ldrex`` and its paired ``strex``. In
-practice this is only usually a risk when the extra store is on the same cache
-line as the variable being modified and Clang will only insert stack stores on
-its own, so it is best not to use these operations on variables with automatic
-storage duration.
+the exclusive monitor in between an ``ldrex`` type operation and its paired
+``strex``. In practice this is only usually a risk when the extra store is on
+the same cache line as the variable being modified and Clang will only insert
+stack stores on its own, so it is best not to use these operations on variables
+with automatic storage duration.
 
 Also, loads and stores may be implicit in code written between the ``ldrex`` and
 ``strex``. Clang will not necessarily mitigate the effects of these either, so
@@ -1667,3 +1687,190 @@
 
 Use ``__has_feature(memory_sanitizer)`` to check if the code is being built
 with :doc:`MemorySanitizer`.
+
+
+Extensions for selectively disabling optimization
+=================================================
+
+Clang provides a mechanism for selectively disabling optimizations in functions
+and methods.
+
+To disable optimizations in a single function definition, the GNU-style or C++11
+non-standard attribute ``optnone`` can be used.
+
+.. code-block:: c++
+
+  // The following functions will not be optimized.
+  // GNU-style attribute
+  __attribute__((optnone)) int foo() {
+    // ... code
+  }
+  // C++11 attribute
+  [[clang::optnone]] int bar() {
+    // ... code
+  }
+
+To facilitate disabling optimization for a range of function definitions, a
+range-based pragma is provided. Its syntax is ``#pragma clang optimize``
+followed by ``off`` or ``on``.
+
+All function definitions in the region between an ``off`` and the following
+``on`` will be decorated with the ``optnone`` attribute unless doing so would
+conflict with explicit attributes already present on the function (e.g. the
+ones that control inlining).
+
+.. code-block:: c++
+
+  #pragma clang optimize off
+  // This function will be decorated with optnone.
+  int foo() {
+    // ... code
+  }
+
+  // optnone conflicts with always_inline, so bar() will not be decorated.
+  __attribute__((always_inline)) int bar() {
+    // ... code
+  }
+  #pragma clang optimize on
+
+If no ``on`` is found to close an ``off`` region, the end of the region is the
+end of the compilation unit.
+
+Note that a stray ``#pragma clang optimize on`` does not selectively enable
+additional optimizations when compiling at low optimization levels. This feature
+can only be used to selectively disable optimizations.
+
+The pragma has an effect on functions only at the point of their definition; for
+function templates, this means that the state of the pragma at the point of an
+instantiation is not necessarily relevant. Consider the following example:
+
+.. code-block:: c++
+
+  template<typename T> T twice(T t) {
+    return 2 * t;
+  }
+
+  #pragma clang optimize off
+  template<typename T> T thrice(T t) {
+    return 3 * t;
+  }
+
+  int container(int a, int b) {
+    return twice(a) + thrice(b);
+  }
+  #pragma clang optimize on
+
+In this example, the definition of the template function ``twice`` is outside
+the pragma region, whereas the definition of ``thrice`` is inside the region.
+The ``container`` function is also in the region and will not be optimized, but
+it causes the instantiation of ``twice`` and ``thrice`` with an ``int`` type; of
+these two instantiations, ``twice`` will be optimized (because its definition
+was outside the region) and ``thrice`` will not be optimized.
+
+Extensions for loop hint optimizations
+======================================
+
+The ``#pragma clang loop`` directive is used to specify hints for optimizing the
+subsequent for, while, do-while, or c++11 range-based for loop. The directive
+provides options for vectorization, interleaving, and unrolling. Loop hints can
+be specified before any loop and will be ignored if the optimization is not safe
+to apply.
+
+Vectorization and Interleaving
+------------------------------
+
+A vectorized loop performs multiple iterations of the original loop
+in parallel using vector instructions. The instruction set of the target
+processor determines which vector instructions are available and their vector
+widths. This restricts the types of loops that can be vectorized. The vectorizer
+automatically determines if the loop is safe and profitable to vectorize. A
+vector instruction cost model is used to select the vector width.
+
+Interleaving multiple loop iterations allows modern processors to further
+improve instruction-level parallelism (ILP) using advanced hardware features,
+such as multiple execution units and out-of-order execution. The vectorizer uses
+a cost model that depends on the register pressure and generated code size to
+select the interleaving count.
+
+Vectorization is enabled by ``vectorize(enable)`` and interleaving is enabled
+by ``interleave(enable)``. This is useful when compiling with ``-Os`` to
+manually enable vectorization or interleaving.
+
+.. code-block:: c++
+
+  #pragma clang loop vectorize(enable)
+  #pragma clang loop interleave(enable)
+  for(...) {
+    ...
+  }
+
+The vector width is specified by ``vectorize_width(_value_)`` and the interleave
+count is specified by ``interleave_count(_value_)``, where
+_value_ is a positive integer. This is useful for specifying the optimal
+width/count of the set of target architectures supported by your application.
+
+.. code-block:: c++
+
+  #pragma clang loop vectorize_width(2)
+  #pragma clang loop interleave_count(2)
+  for(...) {
+    ...
+  }
+
+Specifying a width/count of 1 disables the optimization, and is equivalent to
+``vectorize(disable)`` or ``interleave(disable)``.
+
+Loop Unrolling
+--------------
+
+Unrolling a loop reduces the loop control overhead and exposes more
+opportunities for ILP. Loops can be fully or partially unrolled. Full unrolling
+eliminates the loop and replaces it with an enumerated sequence of loop
+iterations. Full unrolling is only possible if the loop trip count is known at
+compile time. Partial unrolling replicates the loop body within the loop and
+reduces the trip count.
+
+If ``unroll(enable)`` is specified the unroller will attempt to fully unroll the
+loop if the trip count is known at compile time. If the loop count is not known
+or the fully unrolled code size is greater than the limit specified by the
+`-pragma-unroll-threshold` command line option the loop will be partially
+unrolled subject to the same limit.
+
+.. code-block:: c++
+
+  #pragma clang loop unroll(enable)
+  for(...) {
+    ...
+  }
+
+The unroll count can be specified explicitly with ``unroll_count(_value_)`` where
+_value_ is a positive integer. If this value is greater than the trip count the
+loop will be fully unrolled. Otherwise the loop is partially unrolled subject
+to the `-pragma-unroll-threshold` limit.
+
+.. code-block:: c++
+
+  #pragma clang loop unroll_count(8)
+  for(...) {
+    ...
+  }
+
+Unrolling of a loop can be prevented by specifying ``unroll(disable)``.
+
+Additional Information
+----------------------
+
+For convenience multiple loop hints can be specified on a single line.
+
+.. code-block:: c++
+
+  #pragma clang loop vectorize_width(4) interleave_count(8)
+  for(...) {
+    ...
+  }
+
+If an optimization cannot be applied any hints that apply to it will be ignored.
+For example, the hint ``vectorize_width(4)`` is ignored if the loop is not
+proven safe to vectorize. To identify and diagnose optimization issues use
+`-Rpass`, `-Rpass-missed`, and `-Rpass-analysis` command line options. See the
+user guide for details.
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
index c308635..4988053 100644
--- a/docs/LibASTMatchersReference.html
+++ b/docs/LibASTMatchersReference.html
@@ -1966,6 +1966,31 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('hasGlobalStorage0')"><a name="hasGlobalStorage0Anchor">hasGlobalStorage</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="hasGlobalStorage0"><pre>Matches a variable declaration that does not have local storage.
+
+Example matches y and z (matcher = varDecl(hasGlobalStorage())
+void f() {
+  int x;
+  static int y;
+}
+int z;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('hasLocalStorage0')"><a name="hasLocalStorage0Anchor">hasLocalStorage</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="hasLocalStorage0"><pre>Matches a variable declaration that has function scope and is a
+non-static local variable.
+
+Example matches x (matcher = varDecl(hasLocalStorage())
+void f() {
+  int x;
+  static int y;
+}
+int z;
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('isDefinition1')"><a name="isDefinition1Anchor">isDefinition</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isDefinition1"><pre>Matches if a declaration has a body attached.
 
diff --git a/docs/MSVCCompatibility.rst b/docs/MSVCCompatibility.rst
index 683ce93..32efb76 100644
--- a/docs/MSVCCompatibility.rst
+++ b/docs/MSVCCompatibility.rst
@@ -19,7 +19,7 @@
 
 First, Clang attempts to be ABI-compatible, meaning that Clang-compiled code
 should be able to link against MSVC-compiled code successfully.  However, C++
-ABIs are particular large and complicated, and Clang's support for MSVC's C++
+ABIs are particularly large and complicated, and Clang's support for MSVC's C++
 ABI is a work in progress.  If you don't require MSVC ABI compatibility or don't
 want to use Microsoft's C and C++ runtimes, the mingw32 toolchain might be a
 better fit for your project.
@@ -43,14 +43,14 @@
 
 The status of major ABI-impacting C++ features:
 
-* Record layout: :good:`Mostly complete`.  We've tested this with a fuzzer, and
-  most of the remaining failures involve ``#pragma pack``,
-  ``__declspec(align(N))``, or other pragmas.
+* Record layout: :good:`Complete`.  We've tested this with a fuzzer and have
+  fixed all known bugs.
 
 * Class inheritance: :good:`Mostly complete`.  This covers all of the standard
   OO features you would expect: virtual method inheritance, multiple
   inheritance, and virtual inheritance.  Every so often we uncover a bug where
-  our tables are incompatible, but this is pretty well in hand.
+  our tables are incompatible, but this is pretty well in hand.  This feature
+  has also been fuzz tested.
 
 * Name mangling: :good:`Ongoing`.  Every new C++ feature generally needs its own
   mangling.  For example, member pointer template arguments have an interesting
@@ -78,47 +78,64 @@
   enabling stack traces in all modern Windows debuggers.  Clang does not emit
   any type info or description of variable layout.
 
-* `RTTI`_: :none:`Unstarted`.  See the bug for a discussion of what needs to
-  happen first.
-
-.. _RTTI: http://llvm.org/PR18951
+* RTTI: :good:`Complete`.  Generation of RTTI data structures has been
+  finished, along with support for the ``/GR`` flag.
 
 * Exceptions and SEH: :none:`Unstarted`.  Clang can parse both constructs, but
-  does not know how to emit compatible handlers.  This depends on RTTI.
+  does not know how to emit compatible handlers.
 
 * Thread-safe initialization of local statics: :none:`Unstarted`.  We are ABI
-  compatible with MSVC 2012, which does not support thread-safe local statics.
-  MSVC 2013 changed the ABI to make initialization of local statics thread safe,
+  compatible with MSVC 2013, which does not support thread-safe local statics.
+  MSVC "14" changed the ABI to make initialization of local statics thread safe,
   and we have not yet implemented this.
 
-* Lambdas in ABI boundaries: :none:`Infeasible`.  It is unlikely that we will
-  ever be fully ABI compatible with lambdas declared in inline functions due to
-  what appears to be a hash code in the name mangling.  Lambdas that are not
-  externally visible should work fine.
+* Lambdas: :good:`Mostly complete`.  Clang is compatible with Microsoft's
+  implementation of lambdas except for providing overloads for conversion to
+  function pointer for different calling conventions.  However, Microsoft's
+  extension is non-conforming.
 
 Template instantiation and name lookup
 ======================================
 
-In addition to the usual `dependent name lookup FAQs`_, Clang is often unable to
-parse certain invalid C++ constructs that MSVC allows.  As of this writing,
-Clang will reject code with missing ``typename`` annotations:
+MSVC allows many invalid constructs in class templates that Clang has
+historically rejected.  In order to parse widely distributed headers for
+libraries such as the Active Template Library (ATL) and Windows Runtime Library
+(WRL), some template rules have been relaxed or extended in Clang on Windows.
 
-.. _dependent name lookup FAQs:
+The first major semantic difference is that MSVC appears to defer all parsing
+an analysis of inline method bodies in class templates until instantiation
+time.  By default on Windows, Clang attempts to follow suit.  This behavior is
+controlled by the ``-fdelayed-template-parsing`` flag.  While Clang delays
+parsing of method bodies, it still parses the bodies *before* template argument
+substitution, which is not what MSVC does.  The following compatibility tweaks
+are necessary to parse the the template in those cases.
+
+MSVC allows some name lookup into dependent base classes.  Even on other
+platforms, this has been a `frequently asked question`_ for Clang users.  A
+dependent base class is a base class that depends on the value of a template
+parameter.  Clang cannot see any of the names inside dependent bases while it
+is parsing your template, so the user is sometimes required to use the
+``typename`` keyword to assist the parser.  On Windows, Clang attempts to
+follow the normal lookup rules, but if lookup fails, it will assume that the
+user intended to find the name in a dependent base.  While parsing the
+following program, Clang will recover as if the user had written the
+commented-out code:
+
+.. _frequently asked question:
   http://clang.llvm.org/compatibility.html#dep_lookup
 
 .. code-block:: c++
 
-  struct X {
-    typedef int type;
+  template <typename T>
+  struct Foo : T {
+    void f() {
+      /*typename*/ T::UnknownType x =  /*this->*/unknownMember;
+    }
   };
-  template<typename T> int f() {
-    // missing typename keyword
-    return sizeof(/*typename*/ T::type);
-  }
-  template void f<X>();
 
-Accepting code like this is ongoing work.  Ultimately, it may be cleaner to
-`implement a token-based template instantiation mode`_ than it is to add
-compatibility hacks to the existing AST-based instantiation.
+After recovery, Clang warns the user that this code is non-standard and issues
+a hint suggesting how to fix the problem.
 
-.. _implement a token-based template instantiation mode: http://llvm.org/PR18714
+As of this writing, Clang is able to compile a simple ATL hello world
+application.  There are still issues parsing WRL headers for modern Windows 8
+apps, but they should be addressed soon.
diff --git a/docs/PTHInternals.rst b/docs/PTHInternals.rst
index 10dda61..7401cf9 100644
--- a/docs/PTHInternals.rst
+++ b/docs/PTHInternals.rst
@@ -135,11 +135,11 @@
 an algorithmic level, especially when one considers header files of
 arbitrary size.
 
-There are plans to potentially implement an complementary PCH
-implementation for Clang based on the lazy deserialization of ASTs. This
-approach would theoretically have the same constant-time algorithmic
-advantages just mentioned but would also retain some of the strengths of
-PTH such as reduced memory pressure (ideal for multi-core builds).
+There is also a PCH implementation for Clang based on the lazy
+deserialization of ASTs. This approach theoretically has the same
+constant-time algorithmic advantages just mentioned but also retains some
+of the strengths of PTH such as reduced memory pressure (ideal for
+multi-core builds).
 
 Internal PTH Optimizations
 --------------------------
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index df27af9..c99262e 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -51,10 +51,10 @@
   GCC 4.7 changed the mingw ABI. Clang 3.4 and older use the GCC 4.6
   ABI. Clang 3.5 and newer use the GCC 4.7 abi.
 
-- The __has_attribute feature test is now target-aware. Older versions of Clang 
-  would return true when the attribute spelling was known, regardless of whether 
-  the attribute was available to the specific target. Clang now returns true only 
-  when the attribute pertains to the current compilation target.
+- The __has_attribute feature test is now target-aware. Older versions of Clang
+  would return true when the attribute spelling was known, regardless of whether
+  the attribute was available to the specific target. Clang now returns true
+  only when the attribute pertains to the current compilation target.
 
 
 Improvements to Clang's diagnostics
@@ -92,6 +92,20 @@
 `-fcatch-undefined-behavior` and `-fbounds-checking` were removed in favor of
 `-fsanitize=` family of flags.
 
+It is now possible to get optimization reports from the major transformation
+passes via three new flags: `-Rpass`, `-Rpass-missed` and `-Rpass-analysis`.
+These flags take a POSIX regular expression which indicates the name
+of the pass (or passes) that should emit optimization remarks.
+
+New Pragmas in Clang
+-----------------------
+
+Loop optimization hints can be specified using the new `#pragma clang loop`
+directive just prior to the desired loop. The directive allows vectorization,
+interleaving, and unrolling to be enabled or disabled. Vector width as well
+as interleave and unrolling count can be manually specified.  See language
+extensions for details.
+
 C Language Changes in Clang
 ---------------------------
 
@@ -139,6 +153,16 @@
 Static Analyzer
 ---------------
 
+The `-analyzer-config` options are now passed from scan-build through to
+ccc-analyzer and then to Clang.
+
+With the option `-analyzer-config stable-report-filename=true`,
+instead of `report-XXXXXX.html`, scan-build/clang analyzer generate
+`report-<filename>-<function, method name>-<function position>-<id>.html`.
+(id = i++ for several issues found in the same function/method).
+
+List the function/method name in the index page of scan-build.
+
 ...
 
 Core Analysis Improvements
diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst
index 19603d4..90a0e53 100644
--- a/docs/UsersManual.rst
+++ b/docs/UsersManual.rst
@@ -531,6 +531,70 @@
 The -fno-crash-diagnostics flag can be helpful for speeding the process
 of generating a delta reduced test case.
 
+Options to Emit Optimization Reports
+------------------------------------
+
+Optimization reports trace, at a high-level, all the major decisions
+done by compiler transformations. For instance, when the inliner
+decides to inline function ``foo()`` into ``bar()``, or the loop unroller
+decides to unroll a loop N times, or the vectorizer decides to
+vectorize a loop body.
+
+Clang offers a family of flags which the optimizers can use to emit
+a diagnostic in three cases:
+
+1. When the pass makes a transformation (:option:`-Rpass`).
+
+2. When the pass fails to make a transformation (:option:`-Rpass-missed`).
+
+3. When the pass determines whether or not to make a transformation
+   (:option:`-Rpass-analysis`).
+
+NOTE: Although the discussion below focuses on :option:`-Rpass`, the exact
+same options apply to :option:`-Rpass-missed` and :option:`-Rpass-analysis`.
+
+Since there are dozens of passes inside the compiler, each of these flags
+take a regular expression that identifies the name of the pass which should
+emit the associated diagnostic. For example, to get a report from the inliner,
+compile the code with:
+
+.. code-block:: console
+
+   $ clang -O2 -Rpass=inline code.cc -o code
+   code.cc:4:25: remark: foo inlined into bar [-Rpass=inline]
+   int bar(int j) { return foo(j, j - 2); }
+                           ^
+
+Note that remarks from the inliner are identified with `[-Rpass=inline]`.
+To request a report from every optimization pass, you should use
+:option:`-Rpass=.*` (in fact, you can use any valid POSIX regular
+expression). However, do not expect a report from every transformation
+made by the compiler. Optimization remarks do not really make sense
+outside of the major transformations (e.g., inlining, vectorization,
+loop optimizations) and not every optimization pass supports this
+feature.
+
+Current limitations
+^^^^^^^^^^^^^^^^^^^
+
+1. For :option:`-Rpass` to provide column information, you
+   need to enable it explicitly. That is, you need to add
+   :option:`-gcolumn-info`. If you omit this, remarks will only show
+   line information.
+
+2. Optimization remarks that refer to function names will display the
+   mangled name of the function. Since these remarks are emitted by the
+   back end of the compiler, it does not know anything about the input
+   language, nor its mangling rules.
+
+3. Some source locations are not displayed correctly. The front end has
+   a more detailed source location tracking than the locations included
+   in the debug info (e.g., the front end can locate code inside macro
+   expansions). However, the locations used by :option:`-Rpass` are
+   translated from debug annotations. That translation can be lossy,
+   which results in some remarks having no location information.
+
+
 Language and Target-Independent Features
 ========================================
 
@@ -872,10 +936,6 @@
       ``-fsanitize=address``:
       :doc:`AddressSanitizer`, a memory error
       detector.
-   -  ``-fsanitize=init-order``: Make AddressSanitizer check for
-      dynamic initialization order problems. Implied by ``-fsanitize=address``.
-   -  ``-fsanitize=address-full``: AddressSanitizer with all the
-      experimental features listed below.
    -  ``-fsanitize=integer``: Enables checks for undefined or
       suspicious integer behavior.
    -  .. _opt_fsanitize_thread:
@@ -958,14 +1018,6 @@
    -  ``-fno-sanitize-blacklist``: don't use blacklist file, if it was
       specified earlier in the command line.
 
-   Experimental features of AddressSanitizer (not ready for widespread
-   use, require explicit ``-fsanitize=address``):
-
-   -  ``-fsanitize=use-after-return``: Check for use-after-return
-      errors (accessing local variable after the function exit).
-   -  ``-fsanitize=use-after-scope``: Check for use-after-scope errors
-      (accesing local variable after it went out of scope).
-
    Extra features of MemorySanitizer (require explicit
    ``-fsanitize=memory``):
 
@@ -1065,8 +1117,29 @@
    only. This only applies to the AArch64 architecture.
 
 
-Using Sampling Profilers for Optimization
------------------------------------------
+Profile Guided Optimization
+---------------------------
+
+Profile information enables better optimization. For example, knowing that a
+branch is taken very frequently helps the compiler make better decisions when
+ordering basic blocks. Knowing that a function ``foo`` is called more
+frequently than another function ``bar`` helps the inliner.
+
+Clang supports profile guided optimization with two different kinds of
+profiling. A sampling profiler can generate a profile with very low runtime
+overhead, or you can build an instrumented version of the code that collects
+more detailed profile information. Both kinds of profiles can provide execution
+counts for instructions in the code and information on branches taken and
+function invocation.
+
+Regardless of which kind of profiling you use, be careful to collect profiles
+by running your code with inputs that are representative of the typical
+behavior. Code that is not exercised in the profile will be optimized as if it
+is unimportant, and the compiler may make poor optimization choices for code
+that is disproportionately used while profiling.
+
+Using Sampling Profilers
+^^^^^^^^^^^^^^^^^^^^^^^^
 
 Sampling profilers are used to collect runtime information, such as
 hardware counters, while your application executes. They are typically
@@ -1074,14 +1147,6 @@
 sample data collected by the profiler can be used during compilation
 to determine what the most executed areas of the code are.
 
-In particular, sample profilers can provide execution counts for all
-instructions in the code and information on branches taken and function
-invocation. The compiler can use this information in its optimization
-cost models. For example, knowing that a branch is taken very
-frequently helps the compiler make better decisions when ordering
-basic blocks. Knowing that a function ``foo`` is called more
-frequently than another function ``bar`` helps the inliner.
-
 Using the data from a sample profiler requires some changes in the way
 a program is built. Before the compiler can use profiling information,
 the code needs to execute under the profiler. The following is the
@@ -1141,7 +1206,7 @@
 
 
 Sample Profile Format
-^^^^^^^^^^^^^^^^^^^^^
+"""""""""""""""""""""
 
 If you are not using Linux Perf to collect profiles, you will need to
 write a conversion tool from your profiler to LLVM's format. This section
@@ -1225,6 +1290,60 @@
    with ``baz()`` being the relatively more frequently called target.
 
 
+Profiling with Instrumentation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Clang also supports profiling via instrumentation. This requires building a
+special instrumented version of the code and has some runtime
+overhead during the profiling, but it provides more detailed results than a
+sampling profiler. It also provides reproducible results, at least to the
+extent that the code behaves consistently across runs.
+
+Here are the steps for using profile guided optimization with
+instrumentation:
+
+1. Build an instrumented version of the code by compiling and linking with the
+   ``-fprofile-instr-generate`` option.
+
+   .. code-block:: console
+
+     $ clang++ -O2 -fprofile-instr-generate code.cc -o code
+
+2. Run the instrumented executable with inputs that reflect the typical usage.
+   By default, the profile data will be written to a ``default.profraw`` file
+   in the current directory. You can override that default by setting the
+   ``LLVM_PROFILE_FILE`` environment variable to specify an alternate file.
+   Any instance of ``%p`` in that file name will be replaced by the process
+   ID, so that you can easily distinguish the profile output from multiple
+   runs.
+
+   .. code-block:: console
+
+     $ LLVM_PROFILE_FILE="code-%p.profraw" ./code
+
+3. Combine profiles from multiple runs and convert the "raw" profile format to
+   the input expected by clang. Use the ``merge`` command of the llvm-profdata
+   tool to do this.
+
+   .. code-block:: console
+
+     $ llvm-profdata merge -output=code.profdata code-*.profraw
+
+   Note that this step is necessary even when there is only one "raw" profile,
+   since the merge operation also changes the file format.
+
+4. Build the code again using the ``-fprofile-instr-use`` option to specify the
+   collected profile data.
+
+   .. code-block:: console
+
+     $ clang++ -O2 -fprofile-instr-use=code.profdata code.cc -o code
+
+   You can repeat step 4 as often as you like without regenerating the
+   profile. As you make changes to your code, clang may no longer be able to
+   use the profile data. It will warn you when this happens.
+
+
 Controlling Size of Debug Information
 -------------------------------------
 
@@ -1244,6 +1363,28 @@
   doesn't contain any other data (e.g. description of local variables or
   function parameters).
 
+.. option:: -fstandalone-debug
+
+  Clang supports a number of optimizations to reduce the size of debug
+  information in the binary. They work based on the assumption that
+  the debug type information can be spread out over multiple
+  compilation units.  For instance, Clang will not emit type
+  definitions for types that are not needed by a module and could be
+  replaced with a forward declaration.  Further, Clang will only emit
+  type info for a dynamic C++ class in the module that contains the
+  vtable for the class.
+
+  The **-fstandalone-debug** option turns off these optimizations.
+  This is useful when working with 3rd-party libraries that don't come
+  with debug information.  Note that Clang will never emit type
+  information for types that are not referenced at all by the program.
+
+.. option:: -fno-standalone-debug
+
+   On Darwin **-fstandalone-debug** is enabled by default. The
+   **-fno-standalone-debug** option can be used to get to turn on the
+   vtable-based optimization described above.
+
 .. option:: -g
 
   Generate complete debug info.
diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod
index 6ccdbba..f7d2eaf 100644
--- a/docs/tools/clang.pod
+++ b/docs/tools/clang.pod
@@ -324,8 +324,9 @@
 
 The B<-fstandalone-debug> option turns off these optimizations.  This
 is useful when working with 3rd-party libraries that don't come with
-debug information.  Note that Clang will never emit type information
-for types that are not referenced at all by the program.
+debug information.  This is the default on Darwin.  Note that Clang
+will never emit type information for types that are not referenced at
+all by the program.
 
 =item B<-fexceptions>
 
diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt
index 10df7e7..d454539 100644
--- a/examples/clang-interpreter/CMakeLists.txt
+++ b/examples/clang-interpreter/CMakeLists.txt
@@ -1,9 +1,10 @@
 set(LLVM_LINK_COMPONENTS
   Core
   ExecutionEngine
+  Interpreter
   JIT
   Support
-  nativecodegen
+  native
   )
 
 add_clang_executable(clang-interpreter
diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp
index 0f083c1..8b8ccfd 100644
--- a/examples/clang-interpreter/main.cpp
+++ b/examples/clang-interpreter/main.cpp
@@ -47,7 +47,7 @@
 
   std::string Error;
   std::unique_ptr<llvm::ExecutionEngine> EE(
-      llvm::ExecutionEngine::createJIT(Mod, &Error));
+      llvm::ExecutionEngine::create(Mod, /*ForceInterpreter*/ false, &Error));
   if (!EE) {
     llvm::errs() << "unable to make execution engine: " << Error << "\n";
     return 255;
@@ -77,6 +77,7 @@
   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
   Driver TheDriver(Path, llvm::sys::getProcessTriple(), Diags);
   TheDriver.setTitle("clang interpreter");
+  TheDriver.setCheckInputsExist(false);
 
   // FIXME: This is a hack to try to force the driver to do something we can
   // recognize. We need to extend the driver library to support this use model
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 3d4a229..f6709f1 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -2139,7 +2139,35 @@
    */
   CXCursor_OMPSimdDirective              = 233,
 
-  CXCursor_LastStmt                      = CXCursor_OMPSimdDirective,
+  /** \brief OpenMP for directive.
+   */
+  CXCursor_OMPForDirective               = 234,
+
+  /** \brief OpenMP sections directive.
+   */
+  CXCursor_OMPSectionsDirective          = 235,
+
+  /** \brief OpenMP section directive.
+   */
+  CXCursor_OMPSectionDirective           = 236,
+
+  /** \brief OpenMP single directive.
+   */
+  CXCursor_OMPSingleDirective            = 237,
+
+  /** \brief OpenMP parallel for directive.
+   */
+  CXCursor_OMPParallelForDirective       = 238,
+
+  /** \brief OpenMP parallel sections directive.
+   */
+  CXCursor_OMPParallelSectionsDirective  = 239,
+
+  /** \brief Windows Structured Exception Handling's leave statement.
+   */
+  CXCursor_SEHLeaveStmt                  = 240,
+
+  CXCursor_LastStmt                      = CXCursor_SEHLeaveStmt,
 
   /**
    * \brief Cursor that represents the translation unit itself.
@@ -2168,8 +2196,12 @@
   CXCursor_PureAttr                      = 409,
   CXCursor_ConstAttr                     = 410,
   CXCursor_NoDuplicateAttr               = 411,
-  CXCursor_LastAttr                      = CXCursor_NoDuplicateAttr,
-     
+  CXCursor_CUDAConstantAttr              = 412,
+  CXCursor_CUDADeviceAttr                = 413,
+  CXCursor_CUDAGlobalAttr                = 414,
+  CXCursor_CUDAHostAttr                  = 415,
+  CXCursor_LastAttr                      = CXCursor_CUDAHostAttr,
+
   /* Preprocessing */
   CXCursor_PreprocessingDirective        = 500,
   CXCursor_MacroDefinition               = 501,
diff --git a/include/clang-c/module.modulemap b/include/clang-c/module.modulemap
new file mode 100644
index 0000000..95a59d6
--- /dev/null
+++ b/include/clang-c/module.modulemap
@@ -0,0 +1,4 @@
+module Clang_C {
+  umbrella "."
+  module * { export * }
+}
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index fb2fdd3..e094301 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -56,8 +56,6 @@
 
   void applyMappings(PreprocessorOptions &PPOpts) const;
 
-  void transferMappingsAndClear(PreprocessorOptions &PPOpts);
-
   void clear(StringRef outputDir = StringRef());
 
 private:
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 6fa7cd8..736a10b 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -50,9 +50,7 @@
   virtual void Initialize(ASTContext &Context) {}
 
   /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
-  /// called by the parser to process every top-level Decl*. Note that D can be
-  /// the head of a chain of Decls (e.g. for `int a, b` the chain will have two
-  /// elements). Use Decl::getNextDeclarator() to walk the chain.
+  /// called by the parser to process every top-level Decl*.
   ///
   /// \returns true to continue parsing, or false to abort parsing.
   virtual bool HandleTopLevelDecl(DeclGroupRef D);
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index b0de90c..0a991cc 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -816,7 +816,7 @@
   /// \brief Retrieve a pointer to the external AST source associated
   /// with this AST context, if any.
   ExternalASTSource *getExternalSource() const {
-    return ExternalSource.getPtr();
+    return ExternalSource.get();
   }
 
   /// \brief Attach an AST mutation listener to the AST context.
@@ -1373,6 +1373,10 @@
   void getObjCEncodingForType(QualType T, std::string &S,
                               const FieldDecl *Field=nullptr) const;
 
+  /// \brief Emit the Objective-C property type encoding for the given
+  /// type \p T into \p S.
+  void getObjCEncodingForPropertyType(QualType T, std::string &S) const;
+
   void getLegacyIntegralTypeEncoding(QualType &t) const;
 
   /// \brief Put the string version of the type qualifiers \p QT into \p S.
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 1635511..484ca4c 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -36,12 +36,9 @@
   void FormatASTNodeDiagnosticArgument(
       DiagnosticsEngine::ArgumentKind Kind,
       intptr_t Val,
-      const char *Modifier,
-      unsigned ModLen,
-      const char *Argument,
-      unsigned ArgLen,
-      const DiagnosticsEngine::ArgumentValue *PrevArgs,
-      unsigned NumPrevArgs,
+      StringRef Modifier,
+      StringRef Argument,
+      ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
       SmallVectorImpl<char> &Output,
       void *Cookie,
       ArrayRef<intptr_t> QualTypeVals);
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
index 109d623..e2dcdbe 100644
--- a/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -423,12 +423,12 @@
   bool TraverseDeclContextHelper(DeclContext *DC);
   bool TraverseFunctionHelper(FunctionDecl *D);
   bool TraverseVarHelper(VarDecl *D);
-  bool TraverseOMPClause(OMPClause *C);
   bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+  bool TraverseOMPClause(OMPClause *C);
 #define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
 #include "clang/Basic/OpenMPKinds.def"
   /// \brief Process clauses with list of variables.
-  template <typename T> void VisitOMPClauseList(T *Node);
+  template <typename T> bool VisitOMPClauseList(T *Node);
 
   typedef SmallVector<Stmt *, 16> StmtsTy;
   typedef SmallVector<StmtsTy *, 4> QueuesTy;
@@ -1207,6 +1207,11 @@
   if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
   TRY_TO(TraverseStmt(D->getBody()));
+  for (const auto &I : D->captures()) {
+    if (I.hasCopyExpr()) {
+      TRY_TO(TraverseStmt(I.getCopyExpr()));
+    }
+  }
   // This return statement makes sure the traversal of nodes in
   // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
   // is skipped - don't remove it.
@@ -1322,8 +1327,13 @@
   return true;
 })
 
-DEF_TRAVERSE_DECL(ObjCPropertyDecl, {// FIXME: implement
-                                    })
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+})
 
 DEF_TRAVERSE_DECL(UsingDecl, {
   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
@@ -2222,6 +2232,7 @@
 DEF_TRAVERSE_STMT(SEHTryStmt, {})
 DEF_TRAVERSE_STMT(SEHExceptStmt, {})
 DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
 DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
 
 DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
@@ -2262,23 +2273,35 @@
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
     OMPExecutableDirective *S) {
-  ArrayRef<OMPClause *> Clauses = S->clauses();
-  for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
-       I != E; ++I)
-    if (!TraverseOMPClause(*I))
-      return false;
+  for (auto *C : S->clauses()) {
+    TRY_TO(TraverseOMPClause(C));
+  }
   return true;
 }
 
-DEF_TRAVERSE_STMT(OMPParallelDirective, {
-  if (!TraverseOMPExecutableDirective(S))
-    return false;
-})
+DEF_TRAVERSE_STMT(OMPParallelDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
-DEF_TRAVERSE_STMT(OMPSimdDirective, {
-  if (!TraverseOMPExecutableDirective(S))
-    return false;
-})
+DEF_TRAVERSE_STMT(OMPSimdDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSingleDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
 // OpenMP clauses.
 template <typename Derived>
@@ -2288,9 +2311,11 @@
   switch (C->getClauseKind()) {
 #define OPENMP_CLAUSE(Name, Class)                                             \
   case OMPC_##Name:                                                            \
-    return getDerived().Visit##Class(static_cast<Class *>(C));
+    TRY_TO(Visit##Class(static_cast<Class *>(C)));                             \
+    break;
 #include "clang/Basic/OpenMPKinds.def"
-  default:
+  case OMPC_threadprivate:
+  case OMPC_unknown:
     break;
   }
   return true;
@@ -2298,77 +2323,125 @@
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
-  TraverseStmt(C->getCondition());
+  TRY_TO(TraverseStmt(C->getCondition()));
   return true;
 }
 
 template <typename Derived>
 bool
 RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
-  TraverseStmt(C->getNumThreads());
+  TRY_TO(TraverseStmt(C->getNumThreads()));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
-  TraverseStmt(C->getSafelen());
+  TRY_TO(TraverseStmt(C->getSafelen()));
   return true;
 }
 
 template <typename Derived>
 bool
 RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
-  TraverseStmt(C->getNumForLoops());
+  TRY_TO(TraverseStmt(C->getNumForLoops()));
   return true;
 }
 
 template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
   return true;
 }
 
 template <typename Derived>
 bool
-RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *C) {
+RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  TRY_TO(TraverseStmt(C->getChunkSize()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
   return true;
 }
 
 template <typename Derived>
 template <typename T>
-void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
-  for (auto *I : Node->varlists())
-    TraverseStmt(I);
+bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+  for (auto *E : Node->varlists()) {
+    TRY_TO(TraverseStmt(E));
+  }
+  return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
     OMPFirstprivateClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
+    OMPLastprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
-  VisitOMPClauseList(C);
-  TraverseStmt(C->getStep());
+  TRY_TO(TraverseStmt(C->getStep()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  TRY_TO(TraverseStmt(C->getAlignment()));
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
+    OMPCopyprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index f654791..ce8b8b7 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -52,8 +52,7 @@
 /// A client can read the relevant info using TypeLoc wrappers, e.g:
 /// @code
 /// TypeLoc TL = TypeSourceInfo->getTypeLoc();
-/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL))
-///   PL->getStarLoc().print(OS, SrcMgr);
+/// TL.getStartLoc().print(OS, SrcMgr);
 /// @endcode
 ///
 class TypeSourceInfo {
@@ -204,9 +203,8 @@
     // C++0x [class.mem]p1:
     //   The enumerators of an unscoped enumeration defined in
     //   the class are members of the class.
-    // FIXME: support C++0x scoped enumerations.
     if (isa<EnumDecl>(DC))
-      DC = DC->getParent();
+      DC = DC->getRedeclContext();
 
     return DC->isRecord();
   }
@@ -1897,6 +1895,11 @@
     return getType()->getAs<FunctionType>()->getReturnType();
   }
 
+  /// \brief Attempt to compute an informative source range covering the
+  /// function return type. This may omit qualifiers and other information with
+  /// limited representation in the AST.
+  SourceRange getReturnTypeSourceRange() const;
+
   /// \brief Determine the type of an expression that calls this function.
   QualType getCallResultType() const {
     return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index c77b2b6..607ca4e 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -1000,7 +1000,7 @@
   void print(raw_ostream &OS) const override;
 };
 
-typedef llvm::MutableArrayRef<NamedDecl*> DeclContextLookupResult;
+typedef MutableArrayRef<NamedDecl *> DeclContextLookupResult;
 
 typedef ArrayRef<NamedDecl *> DeclContextLookupConstResult;
 
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 01af64a..72fad7c 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -462,6 +462,9 @@
     /// \brief Whether this class describes a C++ lambda.
     bool IsLambda : 1;
 
+    /// \brief Whether we are currently parsing base specifiers.
+    bool IsParsingBaseSpecifiers : 1;
+
     /// \brief The number of base class specifiers in Bases.
     unsigned NumBases;
 
@@ -685,6 +688,12 @@
     return data().Polymorphic || data().NumVBases != 0;
   }
 
+  void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
+
+  bool isParsingBaseSpecifiers() const {
+    return data().IsParsingBaseSpecifiers;
+  }
+
   /// \brief Sets the base classes of this struct or class.
   void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
 
@@ -2767,9 +2776,9 @@
   static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
   typedef redeclarable_base::redecl_range redecl_range;
-  typedef redeclarable_base::redecl_iterator redecl_iterator;

-  using redeclarable_base::redecls_begin;

-  using redeclarable_base::redecls_end;

+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
   using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 4ca02d2..520f523 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -1927,8 +1927,8 @@
 
   /// getIdentifier - Get the identifier that names the category
   /// interface associated with this implementation.
-  /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
-  /// to mean something different. For example:
+  /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
+  /// with a different meaning. For example:
   /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
   /// returns the class interface name, whereas
   /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
@@ -1945,11 +1945,9 @@
   /// getName - Get the name of identifier for the class interface associated
   /// with this implementation as a StringRef.
   //
-  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
-  // something different.
-  StringRef getName() const {
-    return Id ? Id->getNameStart() : "";
-  }
+  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
+  // meaning.
+  StringRef getName() const { return Id ? Id->getName() : StringRef(); }
 
   /// @brief Get the name of the class associated with this interface.
   //
@@ -2089,8 +2087,8 @@
   /// getName - Get the name of identifier for the class interface associated
   /// with this implementation as a StringRef.
   //
-  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
-  // something different.
+  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
+  // meaning.
   StringRef getName() const {
     assert(getIdentifier() && "Name is not a simple identifier");
     return getIdentifier()->getName();
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 76282a3..1b329dc 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -47,10 +47,10 @@
                    NumVars);
   }
 
-  llvm::MutableArrayRef<Expr *> getVars() {
-    return llvm::MutableArrayRef<Expr *>(
-                                 reinterpret_cast<Expr **>(this + 1),
-                                 NumVars);
+  MutableArrayRef<Expr *> getVars() {
+    return MutableArrayRef<Expr *>(
+                           reinterpret_cast<Expr **>(this + 1),
+                           NumVars);
   }
 
   void setVars(ArrayRef<Expr *> VL);
@@ -62,7 +62,7 @@
   static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
                                                   unsigned ID, unsigned N);
 
-  typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
+  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
   typedef llvm::iterator_range<varlist_iterator> varlist_range;
   typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 483ea79..980a06e 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -86,11 +86,11 @@
 
   unsigned size() const { return NumParams; }
 
-  llvm::ArrayRef<NamedDecl*> asArray() {
-    return llvm::ArrayRef<NamedDecl*>(begin(), size());
+  ArrayRef<NamedDecl*> asArray() {
+    return ArrayRef<NamedDecl*>(begin(), size());
   }
-  llvm::ArrayRef<const NamedDecl*> asArray() const {
-    return llvm::ArrayRef<const NamedDecl*>(begin(), size());
+  ArrayRef<const NamedDecl*> asArray() const {
+    return ArrayRef<const NamedDecl*>(begin(), size());
   }
 
   NamedDecl* getParam(unsigned Idx) {
@@ -203,8 +203,8 @@
   const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
 
   /// \brief Produce this as an array ref.
-  llvm::ArrayRef<TemplateArgument> asArray() const {
-    return llvm::ArrayRef<TemplateArgument>(data(), size());
+  ArrayRef<TemplateArgument> asArray() const {
+    return ArrayRef<TemplateArgument>(data(), size());
   }
 
   /// \brief Retrieve the number of template arguments in this
@@ -380,16 +380,15 @@
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, TemplateArguments->data(),
-            TemplateArguments->size(),
+    Profile(ID, TemplateArguments->asArray(),
             Function->getASTContext());
   }
 
   static void
-  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
-          unsigned NumTemplateArgs, ASTContext &Context) {
-    ID.AddInteger(NumTemplateArgs);
-    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+  Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
+          ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
       TemplateArgs[Arg].Profile(ID, Context);
   }
 };
@@ -597,8 +596,7 @@
 
   template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
   findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
-                         const TemplateArgument *Args, unsigned NumArgs,
-                         void *&InsertPos);
+                         ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   struct CommonBase {
     CommonBase() : InstantiatedFromMember(nullptr, false) { }
@@ -819,8 +817,8 @@
 
   /// \brief Return the specialization with the provided arguments if it exists,
   /// otherwise return the insertion point.
-  FunctionDecl *findSpecialization(const TemplateArgument *Args,
-                                   unsigned NumArgs, void *&InsertPos);
+  FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
+                                   void *&InsertPos);
 
   FunctionTemplateDecl *getCanonicalDecl() override {
     return cast<FunctionTemplateDecl>(
@@ -1628,14 +1626,14 @@
   SourceRange getSourceRange() const override LLVM_READONLY;
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
-    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
+    Profile(ID, TemplateArgs->asArray(), getASTContext());
   }
 
   static void
-  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
-          unsigned NumTemplateArgs, ASTContext &Context) {
-    ID.AddInteger(NumTemplateArgs);
-    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+  Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
+          ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
       TemplateArgs[Arg].Profile(ID, Context);
   }
 
@@ -1878,8 +1876,7 @@
   /// \brief Return the specialization with the provided arguments if it exists,
   /// otherwise return the insertion point.
   ClassTemplateSpecializationDecl *
-  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
-                     void *&InsertPos);
+  findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   /// \brief Insert the specified specialization knowing that it is not already
   /// in. InsertPos must be obtained from findSpecialization.
@@ -1925,8 +1922,7 @@
   /// \brief Return the partial specialization with the provided arguments if it
   /// exists, otherwise return the insertion point.
   ClassTemplatePartialSpecializationDecl *
-  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
-                            void *&InsertPos);
+  findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   /// \brief Insert the specified partial specialization knowing that it is not
   /// already in. InsertPos must be obtained from findPartialSpecialization.
@@ -2487,14 +2483,14 @@
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
-    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
+    Profile(ID, TemplateArgs->asArray(), getASTContext());
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID,
-                      const TemplateArgument *TemplateArgs,
-                      unsigned NumTemplateArgs, ASTContext &Context) {
-    ID.AddInteger(NumTemplateArgs);
-    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+                      ArrayRef<TemplateArgument> TemplateArgs,
+                      ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
       TemplateArgs[Arg].Profile(ID, Context);
   }
 
@@ -2715,8 +2711,7 @@
   /// \brief Return the specialization with the provided arguments if it exists,
   /// otherwise return the insertion point.
   VarTemplateSpecializationDecl *
-  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
-                     void *&InsertPos);
+  findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   /// \brief Insert the specified specialization knowing that it is not already
   /// in. InsertPos must be obtained from findSpecialization.
@@ -2752,8 +2747,7 @@
   /// \brief Return the partial specialization with the provided arguments if it
   /// exists, otherwise return the insertion point.
   VarTemplatePartialSpecializationDecl *
-  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
-                            void *&InsertPos);
+  findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   /// \brief Insert the specified partial specialization knowing that it is not
   /// already in. InsertPos must be obtained from findPartialSpecialization.
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index e0b3c05..e208280 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -619,7 +619,7 @@
   /// constant.
   bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
                                 const FunctionDecl *Callee,
-                                llvm::ArrayRef<const Expr*> Args) const;
+                                ArrayRef<const Expr*> Args) const;
 
   /// \brief Enumeration used to describe the kind of Null pointer constant
   /// returned from \c isNullPointerConstant().
@@ -3909,6 +3909,7 @@
 
   // Iterators
   child_range children() {
+    // FIXME: This does not include the array filler expression.
     if (InitExprs.empty()) return child_range();
     return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
   }
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index e740836..a8d1199 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -36,33 +36,6 @@
   struct ThunkInfo;
   class VarDecl;
 
-/// MangleBuffer - a convenient class for storing a name which is
-/// either the result of a mangling or is a constant string with
-/// external memory ownership.
-class MangleBuffer {
-public:
-  void setString(StringRef Ref) {
-    String = Ref;
-  }
-
-  SmallVectorImpl<char> &getBuffer() {
-    return Buffer;
-  }
-
-  StringRef getString() const {
-    if (!String.empty()) return String;
-    return Buffer.str();
-  }
-
-  operator StringRef() const {
-    return getString();
-  }
-
-private:
-  StringRef String;
-  SmallString<256> Buffer;
-};
-
 /// MangleContext - Context for tracking state which persists across multiple
 /// calls to the C++ name mangler.
 class MangleContext {
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 2be6882..95cb11c 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -76,8 +76,8 @@
 
 protected:
   /// \brief Fetches list of variables associated with this clause.
-  llvm::MutableArrayRef<Expr *> getVarRefs() {
-    return llvm::MutableArrayRef<Expr *>(
+  MutableArrayRef<Expr *> getVarRefs() {
+    return MutableArrayRef<Expr *>(
         reinterpret_cast<Expr **>(
             reinterpret_cast<char *>(this) +
             llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
@@ -108,7 +108,7 @@
       : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
 
 public:
-  typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
+  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
   typedef llvm::iterator_range<varlist_iterator> varlist_range;
   typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
@@ -431,7 +431,8 @@
   StmtRange children() { return StmtRange(); }
 };
 
-/// \brief This represents 'proc_bind' clause in the '#pragma omp ...' directive.
+/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
+/// directive.
 ///
 /// \code
 /// #pragma omp parallel proc_bind(master)
@@ -471,8 +472,8 @@
   /// \param EndLoc Ending location of the clause.
   ///
   OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
-                   SourceLocation StartLoc, SourceLocation LParenLoc,
-                   SourceLocation EndLoc)
+                    SourceLocation StartLoc, SourceLocation LParenLoc,
+                    SourceLocation EndLoc)
       : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
         Kind(A), KindKwLoc(ALoc) {}
 
@@ -501,6 +502,162 @@
   StmtRange children() { return StmtRange(); }
 };
 
+/// \brief This represents 'schedule' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for schedule(static, 3)
+/// \endcode
+/// In this example directive '#pragma omp for' has 'schedule' clause with
+/// arguments 'static' and '3'.
+///
+class OMPScheduleClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief A kind of the 'schedule' clause.
+  OpenMPScheduleClauseKind Kind;
+  /// \brief Start location of the schedule ind in source code.
+  SourceLocation KindLoc;
+  /// \brief Location of ',' (if any).
+  SourceLocation CommaLoc;
+  /// \brief Chunk size.
+  Stmt *ChunkSize;
+
+  /// \brief Set schedule kind.
+  ///
+  /// \param K Schedule kind.
+  ///
+  void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }
+  /// \brief Sets the location of '('.
+  ///
+  /// \param Loc Location of '('.
+  ///
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Set schedule kind start location.
+  ///
+  /// \param KLoc Schedule kind location.
+  ///
+  void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+  /// \brief Set location of ','.
+  ///
+  /// \param Loc Location of ','.
+  ///
+  void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
+  /// \brief Set chunk size.
+  ///
+  /// \param E Chunk size.
+  ///
+  void setChunkSize(Expr *E) { ChunkSize = E; }
+
+public:
+  /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size
+  /// expression \a ChunkSize.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param KLoc Starting location of the argument.
+  /// \param CommaLoc Location of ','.
+  /// \param EndLoc Ending location of the clause.
+  /// \param Kind Schedule kind.
+  /// \param ChunkSize Chunk size.
+  ///
+  OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                    SourceLocation KLoc, SourceLocation CommaLoc,
+                    SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
+                    Expr *ChunkSize)
+      : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {}
+
+  /// \brief Build an empty clause.
+  ///
+  explicit OMPScheduleClause()
+      : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
+        Kind(OMPC_SCHEDULE_unknown), ChunkSize(nullptr) {}
+
+  /// \brief Get kind of the clause.
+  ///
+  OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }
+  /// \brief Get location of '('.
+  ///
+  SourceLocation getLParenLoc() { return LParenLoc; }
+  /// \brief Get kind location.
+  ///
+  SourceLocation getScheduleKindLoc() { return KindLoc; }
+  /// \brief Get location of ','.
+  ///
+  SourceLocation getCommaLoc() { return CommaLoc; }
+  /// \brief Get chunk size.
+  ///
+  Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSize); }
+  /// \brief Get chunk size.
+  ///
+  Expr *getChunkSize() const { return dyn_cast_or_null<Expr>(ChunkSize); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_schedule;
+  }
+
+  StmtRange children() { return StmtRange(&ChunkSize, &ChunkSize + 1); }
+};
+
+/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for ordered
+/// \endcode
+/// In this example directive '#pragma omp for' has 'ordered' clause.
+///
+class OMPOrderedClause : public OMPClause {
+public:
+  /// \brief Build 'ordered' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_ordered, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPOrderedClause()
+      : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_ordered;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'nowait' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for nowait
+/// \endcode
+/// In this example directive '#pragma omp for' has 'nowait' clause.
+///
+class OMPNowaitClause : public OMPClause {
+public:
+  /// \brief Build 'nowait' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_nowait, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPNowaitClause()
+      : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_nowait;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
 /// \brief This represents clause 'private' in the '#pragma omp ...' directives.
 ///
 /// \code
@@ -620,6 +777,66 @@
   }
 };
 
+/// \brief This represents clause 'lastprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd lastprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'lastprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPLastprivateClause : public OMPVarListClause<OMPLastprivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
+                                               LParenLoc, EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPLastprivateClause(unsigned N)
+      : OMPVarListClause<OMPLastprivateClause>(
+            OMPC_lastprivate, SourceLocation(), SourceLocation(),
+            SourceLocation(), N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPLastprivateClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_lastprivate;
+  }
+};
+
 /// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
 ///
 /// \code
@@ -679,6 +896,99 @@
   }
 };
 
+/// \brief This represents clause 'reduction' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp parallel reduction(+:a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'reduction'
+/// with operator '+' and the variables 'a' and 'b'.
+///
+class OMPReductionClause : public OMPVarListClause<OMPReductionClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+  /// \brief Nested name specifier for C++.
+  NestedNameSpecifierLoc QualifierLoc;
+  /// \brief Name of custom operator.
+  DeclarationNameInfo NameInfo;
+
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param ColonLoc Location of ':'.
+  /// \param N Number of the variables in the clause.
+  /// \param QualifierLoc The nested-name qualifier with location information
+  /// \param NameInfo The full name info for reduction identifier.
+  ///
+  OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                     SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N,
+                     NestedNameSpecifierLoc QualifierLoc,
+                     const DeclarationNameInfo &NameInfo)
+      : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc,
+                                             LParenLoc, EndLoc, N),
+        ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPReductionClause(unsigned N)
+      : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(),
+                                             SourceLocation(), SourceLocation(),
+                                             N),
+        ColonLoc(), QualifierLoc(), NameInfo() {}
+
+  /// \brief Sets location of ':' symbol in clause.
+  void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+  /// \brief Sets the name info for specified reduction identifier.
+  void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
+  /// \brief Sets the nested name specifier.
+  void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL The variables in the clause.
+  /// \param QualifierLoc The nested-name qualifier with location information
+  /// \param NameInfo The full name info for reduction identifier.
+  ///
+  static OMPReductionClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
+         NestedNameSpecifierLoc QualifierLoc,
+         const DeclarationNameInfo &NameInfo);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  /// \brief Gets location of ':' symbol in clause.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  /// \brief Gets the name info for specified reduction identifier.
+  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+  /// \brief Gets the nested name specifier.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_reduction;
+  }
+};
+
 /// \brief This represents clause 'linear' in the '#pragma omp ...'
 /// directives.
 ///
@@ -764,6 +1074,91 @@
   }
 };
 
+/// \brief This represents clause 'aligned' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd aligned(a,b : 8)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'aligned'
+/// with variables 'a', 'b' and alignment '8'.
+///
+class OMPAlignedClause : public OMPVarListClause<OMPAlignedClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+
+  /// \brief Sets the alignment for clause.
+  void setAlignment(Expr *A) { *varlist_end() = A; }
+
+  /// \brief Build 'aligned' clause with given number of variables \a NumVars.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param NumVars Number of variables.
+  ///
+  OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation ColonLoc, SourceLocation EndLoc,
+                   unsigned NumVars)
+      : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
+                                           EndLoc, NumVars),
+        ColonLoc(ColonLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param NumVars Number of variables.
+  ///
+  explicit OMPAlignedClause(unsigned NumVars)
+      : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
+                                           SourceLocation(), SourceLocation(),
+                                           NumVars),
+        ColonLoc(SourceLocation()) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL and alignment \a A.
+  ///
+  /// \param C AST Context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  /// \param A Alignment.
+  static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation LParenLoc,
+                                  SourceLocation ColonLoc,
+                                  SourceLocation EndLoc, ArrayRef<Expr *> VL,
+                                  Expr *A);
+
+  /// \brief Creates an empty clause with the place for \a NumVars variables.
+  ///
+  /// \param C AST context.
+  /// \param NumVars Number of variables.
+  ///
+  static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+  /// \brief Sets the location of ':'.
+  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+  /// \brief Returns the location of ':'.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+
+  /// \brief Returns alignment.
+  Expr *getAlignment() { return *varlist_end(); }
+  /// \brief Returns alignment.
+  const Expr *getAlignment() const { return *varlist_end(); }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end() + 1));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_aligned;
+  }
+};
+
 /// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
 ///
 /// \code
@@ -823,6 +1218,66 @@
   }
 };
 
+/// \brief This represents clause 'copyprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp single copyprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp single' has clause 'copyprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyprivateClause : public OMPVarListClause<OMPCopyprivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
+                                               LParenLoc, EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPCopyprivateClause(unsigned N)
+      : OMPVarListClause<OMPCopyprivateClause>(
+            OMPC_copyprivate, SourceLocation(), SourceLocation(),
+            SourceLocation(), N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPCopyprivateClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_copyprivate;
+  }
+};
+
 } // end namespace clang
 
 #endif
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index d000ae7..b4c4fd6 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -428,12 +428,12 @@
   bool TraverseDeclContextHelper(DeclContext *DC);
   bool TraverseFunctionHelper(FunctionDecl *D);
   bool TraverseVarHelper(VarDecl *D);
-  bool TraverseOMPClause(OMPClause *C);
   bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+  bool TraverseOMPClause(OMPClause *C);
 #define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
 #include "clang/Basic/OpenMPKinds.def"
   /// \brief Process clauses with list of variables.
-  template <typename T> void VisitOMPClauseList(T *Node);
+  template <typename T> bool VisitOMPClauseList(T *Node);
 
   struct EnqueueJob {
     Stmt *S;
@@ -1272,6 +1272,11 @@
   if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
   TRY_TO(TraverseStmt(D->getBody()));
+  for (const auto &I : D->captures()) {
+    if (I.hasCopyExpr()) {
+      TRY_TO(TraverseStmt(I.getCopyExpr()));
+    }
+  }
   // This return statement makes sure the traversal of nodes in
   // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
   // is skipped - don't remove it.
@@ -1394,8 +1399,13 @@
   return true;
 })
 
-DEF_TRAVERSE_DECL(ObjCPropertyDecl, {// FIXME: implement
-                                    })
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+})
 
 DEF_TRAVERSE_DECL(UsingDecl, {
   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
@@ -1515,22 +1525,22 @@
 // template declarations.
 #define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND)                                   \
   DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, {                              \
-    TRY_TO(TraverseDecl(D->getTemplatedDecl()));                             \
-    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
-                                                                             \
-    /* By default, we do not traverse the instantiations of
-       class templates since they do not appear in the user code. The
-       following code optionally traverses them.
-       
-       We only traverse the class instantiations when we see the canonical
-       declaration of the template, to ensure we only visit them once. */    \
-    if (getDerived().shouldVisitTemplateInstantiations() &&                  \
-        D == D->getCanonicalDecl())                                          \
-      TRY_TO(TraverseTemplateInstantiations(D));                             \
-                                                                             \
-    /* Note that getInstantiatedFromMemberTemplate() is just a link
-       from a template instantiation back to the template from which
-       it was instantiated, and thus should not be traversed. */             \
+    TRY_TO(TraverseDecl(D->getTemplatedDecl()));                               \
+    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));   \
+                                                                               \
+    /* By default, we do not traverse the instantiations of                    \
+       class templates since they do not appear in the user code. The          \
+       following code optionally traverses them.                               \
+                                                                               \
+       We only traverse the class instantiations when we see the canonical     \
+       declaration of the template, to ensure we only visit them once. */      \
+    if (getDerived().shouldVisitTemplateInstantiations() &&                    \
+        D == D->getCanonicalDecl())                                            \
+      TRY_TO(TraverseTemplateInstantiations(D));                               \
+                                                                               \
+    /* Note that getInstantiatedFromMemberTemplate() is just a link            \
+       from a template instantiation back to the template from which           \
+       it was instantiated, and thus should not be traversed. */               \
   })
 
 DEF_TRAVERSE_TMPL_DECL(Class)
@@ -1656,24 +1666,24 @@
 
 #define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND)               \
   DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, {         \
-    /* The partial specialization. */                                        \
-    if (TemplateParameterList *TPL = D->getTemplateParameters()) {           \
-      for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
-           I != E; ++I) {                                                    \
-        TRY_TO(TraverseDecl(*I));                                            \
-      }                                                                      \
-    }                                                                        \
-    /* The args that remains unspecialized. */                               \
-    TRY_TO(TraverseTemplateArgumentLocsHelper(                               \
-                      D->getTemplateArgsAsWritten()->getTemplateArgs(),      \
-                      D->getTemplateArgsAsWritten()->NumTemplateArgs));      \
-                                                                             \
-    /* Don't need the *TemplatePartialSpecializationHelper, even
-       though that's our parent class -- we already visit all the
-       template args here. */                                                \
-    TRY_TO(Traverse##DECLKIND##Helper(D));                                   \
-                                                                             \
-    /* Instantiations will have been visited with the primary template. */   \
+    /* The partial specialization. */                                          \
+    if (TemplateParameterList *TPL = D->getTemplateParameters()) {             \
+      for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();   \
+           I != E; ++I) {                                                      \
+        TRY_TO(TraverseDecl(*I));                                              \
+      }                                                                        \
+    }                                                                          \
+    /* The args that remains unspecialized. */                                 \
+    TRY_TO(TraverseTemplateArgumentLocsHelper(                                 \
+        D->getTemplateArgsAsWritten()->getTemplateArgs(),                      \
+        D->getTemplateArgsAsWritten()->NumTemplateArgs));                      \
+                                                                               \
+    /* Don't need the *TemplatePartialSpecializationHelper, even               \
+       though that's our parent class -- we already visit all the              \
+       template args here. */                                                  \
+    TRY_TO(Traverse##DECLKIND##Helper(D));                                     \
+                                                                               \
+    /* Instantiations will have been visited with the primary template. */     \
   })
 
 DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
@@ -2244,6 +2254,7 @@
 DEF_TRAVERSE_STMT(SEHTryStmt, {})
 DEF_TRAVERSE_STMT(SEHExceptStmt, {})
 DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
 DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
 
 DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
@@ -2284,23 +2295,35 @@
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
     OMPExecutableDirective *S) {
-  ArrayRef<OMPClause *> Clauses = S->clauses();
-  for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
-       I != E; ++I)
-    if (!TraverseOMPClause(*I))
-      return false;
+  for (auto *C : S->clauses()) {
+    TRY_TO(TraverseOMPClause(C));
+  }
   return true;
 }
 
-DEF_TRAVERSE_STMT(OMPParallelDirective, {
-  if (!TraverseOMPExecutableDirective(S))
-    return false;
-})
+DEF_TRAVERSE_STMT(OMPParallelDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
-DEF_TRAVERSE_STMT(OMPSimdDirective, {
-  if (!TraverseOMPExecutableDirective(S))
-    return false;
-})
+DEF_TRAVERSE_STMT(OMPSimdDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSingleDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
 // OpenMP clauses.
 template <typename Derived>
@@ -2310,9 +2333,11 @@
   switch (C->getClauseKind()) {
 #define OPENMP_CLAUSE(Name, Class)                                             \
   case OMPC_##Name:                                                            \
-    return getDerived().Visit##Class(static_cast<Class *>(C));
+    TRY_TO(Visit##Class(static_cast<Class *>(C)));                             \
+    break;
 #include "clang/Basic/OpenMPKinds.def"
-  default:
+  case OMPC_threadprivate:
+  case OMPC_unknown:
     break;
   }
   return true;
@@ -2320,76 +2345,125 @@
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
-  TraverseStmt(C->getCondition());
+  TRY_TO(TraverseStmt(C->getCondition()));
   return true;
 }
 
 template <typename Derived>
 bool
 RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
-  TraverseStmt(C->getNumThreads());
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
-  TraverseStmt(C->getSafelen());
+  TRY_TO(TraverseStmt(C->getNumThreads()));
   return true;
 }
 
 template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
-  TraverseStmt(C->getNumForLoops());
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
+bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
+  TRY_TO(TraverseStmt(C->getSafelen()));
   return true;
 }
 
 template <typename Derived>
 bool
-RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *C) {
+RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
+  TRY_TO(TraverseStmt(C->getNumForLoops()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  TRY_TO(TraverseStmt(C->getChunkSize()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
   return true;
 }
 
 template <typename Derived>
 template <typename T>
-void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
-  for (auto *I : Node->varlists())
-    TraverseStmt(I);
+bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+  for (auto *E : Node->varlists()) {
+    TRY_TO(TraverseStmt(E));
+  }
+  return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
     OMPFirstprivateClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
+    OMPLastprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
-  VisitOMPClauseList(C);
-  TraverseStmt(C->getStep());
+  TRY_TO(TraverseStmt(C->getStep()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  TRY_TO(TraverseStmt(C->getAlignment()));
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
+    OMPCopyprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 88cbb21..790c8e3 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1477,6 +1477,8 @@
 
   typedef ExprIterator inputs_iterator;
   typedef ConstExprIterator const_inputs_iterator;
+  typedef llvm::iterator_range<inputs_iterator> inputs_range;
+  typedef llvm::iterator_range<const_inputs_iterator> inputs_const_range;
 
   inputs_iterator begin_inputs() {
     return &Exprs[0] + NumOutputs;
@@ -1486,6 +1488,8 @@
     return &Exprs[0] + NumOutputs + NumInputs;
   }
 
+  inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }
+
   const_inputs_iterator begin_inputs() const {
     return &Exprs[0] + NumOutputs;
   }
@@ -1494,10 +1498,16 @@
     return &Exprs[0] + NumOutputs + NumInputs;
   }
 
+  inputs_const_range inputs() const {
+    return inputs_const_range(begin_inputs(), end_inputs());
+  }
+
   // Output expr iterators.
 
   typedef ExprIterator outputs_iterator;
   typedef ConstExprIterator const_outputs_iterator;
+  typedef llvm::iterator_range<outputs_iterator> outputs_range;
+  typedef llvm::iterator_range<const_outputs_iterator> outputs_const_range;
 
   outputs_iterator begin_outputs() {
     return &Exprs[0];
@@ -1505,6 +1515,9 @@
   outputs_iterator end_outputs() {
     return &Exprs[0] + NumOutputs;
   }
+  outputs_range outputs() {
+    return outputs_range(begin_outputs(), end_outputs());
+  }
 
   const_outputs_iterator begin_outputs() const {
     return &Exprs[0];
@@ -1512,6 +1525,9 @@
   const_outputs_iterator end_outputs() const {
     return &Exprs[0] + NumOutputs;
   }
+  outputs_const_range outputs() const {
+    return outputs_const_range(begin_outputs(), end_outputs());
+  }
 
   child_range children() {
     return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
@@ -1920,6 +1936,31 @@
   }
 };
 
+/// Represents a __leave statement.
+///
+class SEHLeaveStmt : public Stmt {
+  SourceLocation LeaveLoc;
+public:
+  explicit SEHLeaveStmt(SourceLocation LL)
+      : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
+
+  /// \brief Build an empty __leave statement.
+  explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) { }
+
+  SourceLocation getLeaveLoc() const { return LeaveLoc; }
+  void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LeaveLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return LeaveLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SEHLeaveStmtClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
 /// \brief This captures a statement into a function. For example, the following
 /// pragma annotated compound statement can be represented as a CapturedStmt,
 /// and this compound statement is the body of an anonymous outlined function.
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 023720a..f6fe473 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -49,10 +49,10 @@
   const unsigned ClausesOffset;
 
   /// \brief Get the clauses storage.
-  llvm::MutableArrayRef<OMPClause *> getClauses() {
+  MutableArrayRef<OMPClause *> getClauses() {
     OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
         reinterpret_cast<char *>(this) + ClausesOffset);
-    return llvm::MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
+    return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
   }
 
 protected:
@@ -67,8 +67,9 @@
   OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
                          SourceLocation StartLoc, SourceLocation EndLoc,
                          unsigned NumClauses, unsigned NumChildren)
-      : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc),
-        NumClauses(NumClauses), NumChildren(NumChildren),
+      : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
+        EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
+        NumChildren(NumChildren),
         ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
                                                llvm::alignOf<OMPClause *>())) {}
 
@@ -85,6 +86,45 @@
   void setAssociatedStmt(Stmt *S) { *child_begin() = S; }
 
 public:
+  /// \brief Iterates over a filtered subrange of clauses applied to a
+  /// directive.
+  ///
+  /// This iterator visits only those declarations that meet some run-time
+  /// criteria.
+  template <class FilterPredicate> class filtered_clause_iterator {
+    ArrayRef<OMPClause *>::const_iterator Current;
+    ArrayRef<OMPClause *>::const_iterator End;
+    FilterPredicate Pred;
+    void SkipToNextClause() {
+      while (Current != End && !Pred(*Current))
+        ++Current;
+    }
+
+  public:
+    typedef const OMPClause *value_type;
+    filtered_clause_iterator() : Current(), End() {}
+    filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
+        : Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
+      SkipToNextClause();
+    }
+    value_type operator*() const { return *Current; }
+    value_type operator->() const { return *Current; }
+    filtered_clause_iterator &operator++() {
+      ++Current;
+      SkipToNextClause();
+      return *this;
+    }
+
+    filtered_clause_iterator operator++(int) {
+      filtered_clause_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    bool operator!() { return Current == End; }
+    operator bool() { return Current != End; }
+  };
+
   /// \brief Returns starting location of directive kind.
   SourceLocation getLocStart() const { return StartLoc; }
   /// \brief Returns ending location of directive.
@@ -230,11 +270,12 @@
   /// \param C AST context.
   /// \param StartLoc Starting location of the directive kind.
   /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
   /// \param Clauses List of clauses.
   /// \param AssociatedStmt Statement, associated with the directive.
   ///
   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
-                                  SourceLocation EndLoc,
+                                  SourceLocation EndLoc, unsigned CollapsedNum,
                                   ArrayRef<OMPClause *> Clauses,
                                   Stmt *AssociatedStmt);
 
@@ -255,6 +296,368 @@
   }
 };
 
+/// \brief This represents '#pragma omp for' directive.
+///
+/// \code
+/// #pragma omp for private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp for' has clauses 'private' with the
+/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
+/// and 'd'.
+///
+class OMPForDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Number of collapsed loops as specified by 'collapse' clause.
+  unsigned CollapsedNum;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                  unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc,
+                               EndLoc, NumClauses, 1),
+        CollapsedNum(CollapsedNum) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1),
+        CollapsedNum(CollapsedNum) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation EndLoc, unsigned CollapsedNum,
+                                 ArrayRef<OMPClause *> Clauses,
+                                 Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place
+  /// for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                      unsigned CollapsedNum, EmptyShell);
+
+  unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPForDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp sections' directive.
+///
+/// \code
+/// #pragma omp sections private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp sections' has clauses 'private' with
+/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
+/// 'c' and 'd'.
+///
+class OMPSectionsDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                       unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
+                               StartLoc, EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPSectionsDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSectionsDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
+                                           unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSectionsDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp section' directive.
+///
+/// \code
+/// #pragma omp section
+/// \endcode
+///
+class OMPSectionDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
+                               StartLoc, EndLoc, 0, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPSectionDirective()
+      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
+                               SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSectionDirective *Create(const ASTContext &C,
+                                     SourceLocation StartLoc,
+                                     SourceLocation EndLoc,
+                                     Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSectionDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp single' directive.
+///
+/// \code
+/// #pragma omp single private(a,b) copyprivate(c,d)
+/// \endcode
+/// In this example directive '#pragma omp single' has clauses 'private' with
+/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
+///
+class OMPSingleDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                     unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
+                               StartLoc, EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPSingleDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSingleDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
+                                         unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSingleDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp parallel for' directive.
+///
+/// \code
+/// #pragma omp parallel for private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel for' has clauses 'private'
+/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
+/// variables 'c' and 'd'.
+///
+class OMPParallelForDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Number of collapsed loops as specified by 'collapse' clause.
+  unsigned CollapsedNum;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                          unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
+                               OMPD_parallel_for, StartLoc, EndLoc, NumClauses,
+                               1),
+        CollapsedNum(CollapsedNum) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
+                               OMPD_parallel_for, SourceLocation(),
+                               SourceLocation(), NumClauses, 1),
+        CollapsedNum(CollapsedNum) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPParallelForDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+         Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place
+  /// for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
+                                              unsigned NumClauses,
+                                              unsigned CollapsedNum,
+                                              EmptyShell);
+
+  unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPParallelForDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp parallel sections' directive.
+///
+/// \code
+/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel sections' has clauses
+/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
+/// and variables 'c' and 'd'.
+///
+class OMPParallelSectionsDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                               unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
+                               OMPD_parallel_sections, StartLoc, EndLoc,
+                               NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPParallelSectionsDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
+                               OMPD_parallel_sections, SourceLocation(),
+                               SourceLocation(), NumClauses, 1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPParallelSectionsDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPParallelSectionsDirective *
+  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
+  }
+};
+
 } // end namespace clang
 
 #endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index d1f428d..9e4a577 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -335,9 +335,9 @@
   }
 
   /// \brief Return the array of arguments in this template argument pack.
-  llvm::ArrayRef<TemplateArgument> getPackAsArray() const {
+  ArrayRef<TemplateArgument> getPackAsArray() const {
     assert(getKind() == Pack);
-    return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
+    return ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
   }
 
   /// \brief Determines whether two template arguments are superficially the
@@ -543,6 +543,10 @@
     return Arguments[I];
   }
 
+  TemplateArgumentLoc &operator[](unsigned I) {
+    return Arguments[I];
+  }
+
   void addArgument(const TemplateArgumentLoc &Loc) {
     Arguments.push_back(Loc);
   }
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 1727762..a20e434 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -4057,11 +4057,14 @@
 /// dependent.
 ///
 /// DependentNameType represents a class of dependent types that involve a
-/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent)
+/// possibly dependent nested-name-specifier (e.g., "T::") followed by a
 /// name of a type. The DependentNameType may start with a "typename" (for a
 /// typename-specifier), "class", "struct", "union", or "enum" (for a
 /// dependent elaborated-type-specifier), or nothing (in contexts where we
 /// know that we must be referring to a type, e.g., in a base class specifier).
+/// Typically the nested-name-specifier is dependent, but in MSVC compatibility
+/// mode, this type is used with non-dependent names to delay name lookup until
+/// instantiation.
 class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
 
   /// \brief The nested name specifier containing the qualifier.
@@ -4076,10 +4079,7 @@
                       /*InstantiationDependent=*/true,
                       /*VariablyModified=*/false,
                       NNS->containsUnexpandedParameterPack()),
-      NNS(NNS), Name(Name) {
-    assert(NNS->isDependent() &&
-           "DependentNameType requires a dependent nested-name-specifier");
-  }
+      NNS(NNS), Name(Name) {}
 
   friend class ASTContext;  // ASTContext creates these
 
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 759af25..2ef5800 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -27,7 +27,7 @@
 /// non-const iterator.
 class UnresolvedSetIterator {
 private:
-  typedef llvm::MutableArrayRef<DeclAccessPair> DeclsTy;
+  typedef MutableArrayRef<DeclAccessPair> DeclsTy;
   typedef DeclsTy::iterator IteratorTy;
 
   IteratorTy ir;
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 0bfdc14..406ec93 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -334,7 +334,7 @@
     AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
                                       TemplateSpecializationType),
     internal::Matcher<TemplateArgument>, InnerMatcher) {
-  llvm::ArrayRef<TemplateArgument> List =
+  ArrayRef<TemplateArgument> List =
       internal::getTemplateSpecializationArgs(Node);
   return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
                              Builder);
@@ -434,7 +434,7 @@
     AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
                                       TemplateSpecializationType),
     unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
-  llvm::ArrayRef<TemplateArgument> List =
+  ArrayRef<TemplateArgument> List =
       internal::getTemplateSpecializationArgs(Node);
   if (List.size() <= N)
     return false;
@@ -686,10 +686,23 @@
 ///   struct B { int x, y; };
 ///   B b = { 5, 6 };
 /// \endcode
-/// initList()
+/// initListExpr()
 ///   matches "{ 1, 2 }" and "{ 5, 6 }"
 const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
 
+/// \brief Matches substitutions of non-type template parameters.
+///
+/// Given
+/// \code
+///   template <int N>
+///   struct A { static const int n = N; };
+///   struct B : public A<42> {};
+/// \endcode
+/// substNonTypeTemplateParmExpr()
+///   matches "N" in the right-hand side of "static const int n = N;"
+const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
+substNonTypeTemplateParmExpr;
+
 /// \brief Matches using declarations.
 ///
 /// Given
@@ -2058,6 +2071,35 @@
           InnerMatcher.matches(*Initializer, Finder, Builder));
 }
 
+/// \brief Matches a variable declaration that has function scope and is a
+/// non-static local variable.
+///
+/// Example matches x (matcher = varDecl(hasLocalStorage())
+/// \code
+/// void f() {
+///   int x;
+///   static int y;
+/// }
+/// int z;
+/// \endcode
+AST_MATCHER(VarDecl, hasLocalStorage) {
+  return Node.hasLocalStorage();
+}
+
+/// \brief Matches a variable declaration that does not have local storage.
+///
+/// Example matches y and z (matcher = varDecl(hasGlobalStorage())
+/// \code
+/// void f() {
+///   int x;
+///   static int y;
+/// }
+/// int z;
+/// \endcode
+AST_MATCHER(VarDecl, hasGlobalStorage) {
+  return Node.hasGlobalStorage();
+}
+
 /// \brief Checks that a call expression or a constructor call expression has
 /// a specific number of arguments (including absent default arguments).
 ///
@@ -3504,15 +3546,15 @@
 /// \brief Matches if a node equals another node.
 ///
 /// \c Decl has pointer identity in the AST.
-inline internal::Matcher<Decl> equalsNode(const Decl *Node) {
-  return internal::makeMatcher(new internal::EqualsNodeMatcher<Decl>(Node));
+AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) {
+  return &Node == Other;
 }
 /// \brief Matches if a node equals another node.
 ///
 /// \c Stmt has pointer identity in the AST.
 ///
-inline internal::Matcher<Stmt> equalsNode(const Stmt *Node) {
-  return internal::makeMatcher(new internal::EqualsNodeMatcher<Stmt>(Node));
+AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
+  return &Node == Other;
 }
 
 /// @}
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index c0dd7b8..12df77c 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -250,7 +250,7 @@
   uint64_t getID() const {
     /// FIXME: Document the requirements this imposes on matcher
     /// implementations (no new() implementation_ during a Matches()).
-    return reinterpret_cast<uint64_t>(Implementation.getPtr());
+    return reinterpret_cast<uint64_t>(Implementation.get());
   }
 
   /// \brief Allows the conversion of a \c Matcher<Type> to a \c
@@ -1126,16 +1126,25 @@
 template <typename P1, typename P2 = VariadicOperatorNoArg,
           typename P3 = VariadicOperatorNoArg,
           typename P4 = VariadicOperatorNoArg,
-          typename P5 = VariadicOperatorNoArg>
+          typename P5 = VariadicOperatorNoArg,
+          typename P6 = VariadicOperatorNoArg,
+          typename P7 = VariadicOperatorNoArg,
+          typename P8 = VariadicOperatorNoArg,
+          typename P9 = VariadicOperatorNoArg>
 class VariadicOperatorMatcher {
 public:
   VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1,
                           const P2 &Param2 = VariadicOperatorNoArg(),
                           const P3 &Param3 = VariadicOperatorNoArg(),
                           const P4 &Param4 = VariadicOperatorNoArg(),
-                          const P5 &Param5 = VariadicOperatorNoArg())
+                          const P5 &Param5 = VariadicOperatorNoArg(),
+                          const P6 &Param6 = VariadicOperatorNoArg(),
+                          const P7 &Param7 = VariadicOperatorNoArg(),
+                          const P8 &Param8 = VariadicOperatorNoArg(),
+                          const P9 &Param9 = VariadicOperatorNoArg())
       : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3),
-        Param4(Param4), Param5(Param5) {}
+        Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7),
+        Param8(Param8), Param9(Param9) {}
 
   template <typename T> operator Matcher<T>() const {
     std::vector<DynTypedMatcher> Matchers;
@@ -1144,6 +1153,10 @@
     addMatcher<T>(Param3, Matchers);
     addMatcher<T>(Param4, Matchers);
     addMatcher<T>(Param5, Matchers);
+    addMatcher<T>(Param6, Matchers);
+    addMatcher<T>(Param7, Matchers);
+    addMatcher<T>(Param8, Matchers);
+    addMatcher<T>(Param9, Matchers);
     return Matcher<T>(
         new VariadicOperatorMatcherInterface<T>(Func, std::move(Matchers)));
   }
@@ -1166,12 +1179,16 @@
   const P3 Param3;
   const P4 Param4;
   const P5 Param5;
+  const P6 Param6;
+  const P7 Param7;
+  const P8 Param8;
+  const P9 Param9;
 };
 
 /// \brief Overloaded function object to generate VariadicOperatorMatcher
 ///   objects from arbitrary matchers.
 ///
-/// It supports 1-5 argument overloaded operator(). More can be added if needed.
+/// It supports 1-9 argument overloaded operator(). More can be added if needed.
 template <unsigned MinCount, unsigned MaxCount>
 struct VariadicOperatorMatcherFunc {
   VariadicOperatorFunction Func;
@@ -1208,6 +1225,43 @@
     return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4,
                                                        P5);
   }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6>
+  typename EnableIfValidArity<
+      6, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6>(
+        Func, P1, P2, P3, P4, P5, P6);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7>
+  typename EnableIfValidArity<
+      7, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7>(
+        Func, P1, P2, P3, P4, P5, P6, P7);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7, typename M8>
+  typename EnableIfValidArity<
+      8, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8>(
+        Func, P1, P2, P3, P4, P5, P6, P7, P8);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7, typename M8, typename M9>
+  typename EnableIfValidArity<
+      9, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8,
+             const M9 &P9) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9>(
+        Func, P1, P2, P3, P4, P5, P6, P7, P8, P9);
+  }
 };
 
 /// @}
@@ -1387,20 +1441,6 @@
   const ValueT ExpectedValue;
 };
 
-template <typename T>
-class EqualsNodeMatcher : public SingleNodeMatcherInterface<T> {
-public:
-  explicit EqualsNodeMatcher(const T *ExpectedNode)
-      : ExpectedNode(ExpectedNode) {}
-
-  bool matchesNode(const T &Node) const override {
-    return &Node == ExpectedNode;
-  }
-
-private:
-  const T *ExpectedNode;
-};
-
 /// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
 /// variadic functor that takes a number of Matcher<TargetT> and returns a
 /// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
@@ -1580,14 +1620,14 @@
 
 // FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
 // APIs for accessing the template argument list.
-inline llvm::ArrayRef<TemplateArgument>
+inline ArrayRef<TemplateArgument>
 getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
   return D.getTemplateArgs().asArray();
 }
 
-inline llvm::ArrayRef<TemplateArgument>
+inline ArrayRef<TemplateArgument>
 getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
-  return llvm::ArrayRef<TemplateArgument>(T.getArgs(), T.getNumArgs());
+  return ArrayRef<TemplateArgument>(T.getArgs(), T.getNumArgs());
 }
 
 struct NotEqualsBoundNodePredicate {
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index 418e577..563372a 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -52,9 +52,9 @@
                                   0)
 #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
                                         Param, OverloadId)                     \
-  inline ReturnType DefineMatcher(const ParamType &Param);                     \
-  typedef ReturnType (&DefineMatcher##_Type##OverloadId)(const ParamType &);   \
-  inline ReturnType DefineMatcher(const ParamType &Param)
+  inline ReturnType DefineMatcher(ParamType const &Param);                     \
+  typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
+  inline ReturnType DefineMatcher(ParamType const &Param)
 
 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
 /// defines a zero parameter function named DefineMatcher() that returns a
@@ -107,21 +107,21 @@
       : public MatcherInterface<Type> {                                        \
   public:                                                                      \
     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
-        const ParamType &A##Param)                                             \
+        ParamType const &A##Param)                                             \
         : Param(A##Param) {}                                                   \
     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
                  BoundNodesTreeBuilder *Builder) const override;               \
                                                                                \
   private:                                                                     \
-    const ParamType Param;                                                     \
+    ParamType const Param;                                                     \
   };                                                                           \
   }                                                                            \
-  inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) {       \
+  inline internal::Matcher<Type> DefineMatcher(ParamType const &Param) {       \
     return internal::makeMatcher(                                              \
         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
   }                                                                            \
   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
-      const ParamType &Param);                                                 \
+      ParamType const &Param);                                                 \
   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
       const Type &Node, ASTMatchFinder *Finder,                                \
       BoundNodesTreeBuilder *Builder) const
@@ -151,25 +151,25 @@
   class matcher_##DefineMatcher##OverloadId##Matcher                           \
       : public MatcherInterface<Type> {                                        \
   public:                                                                      \
-    matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1,  \
-                                                 const ParamType2 &A##Param2)  \
+    matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
+                                                 ParamType2 const &A##Param2)  \
         : Param1(A##Param1), Param2(A##Param2) {}                              \
     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
                  BoundNodesTreeBuilder *Builder) const override;               \
                                                                                \
   private:                                                                     \
-    const ParamType1 Param1;                                                   \
-    const ParamType2 Param2;                                                   \
+    ParamType1 const Param1;                                                   \
+    ParamType2 const Param2;                                                   \
   };                                                                           \
   }                                                                            \
-  inline internal::Matcher<Type> DefineMatcher(const ParamType1 &Param1,       \
-                                               const ParamType2 &Param2) {     \
+  inline internal::Matcher<Type> DefineMatcher(ParamType1 const &Param1,       \
+                                               ParamType2 const &Param2) {     \
     return internal::makeMatcher(                                              \
         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
                                                                    Param2));   \
   }                                                                            \
   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
-      const ParamType1 &Param1, const ParamType2 &Param2);                     \
+      ParamType1 const &Param1, ParamType2 const &Param2);                     \
   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
       const Type &Node, ASTMatchFinder *Finder,                                \
       BoundNodesTreeBuilder *Builder) const
@@ -240,18 +240,18 @@
       : public MatcherInterface<NodeType> {                                    \
   public:                                                                      \
     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
-        const ParamType &A##Param)                                             \
+        ParamType const &A##Param)                                             \
         : Param(A##Param) {}                                                   \
     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
                  BoundNodesTreeBuilder *Builder) const override;               \
                                                                                \
   private:                                                                     \
-    const ParamType Param;                                                     \
+    ParamType const Param;                                                     \
   };                                                                           \
   }                                                                            \
   inline internal::PolymorphicMatcherWithParam1<                               \
       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
-      ReturnTypesF> DefineMatcher(const ParamType &Param) {                    \
+      ReturnTypesF> DefineMatcher(ParamType const &Param) {                    \
     return internal::PolymorphicMatcherWithParam1<                             \
         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
         ReturnTypesF>(Param);                                                  \
@@ -259,7 +259,7 @@
   typedef internal::PolymorphicMatcherWithParam1<                              \
       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
       ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
-      const ParamType &Param);                                                 \
+      ParamType const &Param);                                                 \
   template <typename NodeType, typename ParamT>                                \
   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
       NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
@@ -286,21 +286,21 @@
   class matcher_##DefineMatcher##OverloadId##Matcher                           \
       : public MatcherInterface<NodeType> {                                    \
   public:                                                                      \
-    matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1,  \
-                                                 const ParamType2 &A##Param2)  \
+    matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
+                                                 ParamType2 const &A##Param2)  \
         : Param1(A##Param1), Param2(A##Param2) {}                              \
      bool matches(const NodeType &Node, ASTMatchFinder *Finder,                \
                   BoundNodesTreeBuilder *Builder) const override;              \
                                                                                \
   private:                                                                     \
-    const ParamType1 Param1;                                                   \
-    const ParamType2 Param2;                                                   \
+    ParamType1 const Param1;                                                   \
+    ParamType2 const Param2;                                                   \
   };                                                                           \
   }                                                                            \
   inline internal::PolymorphicMatcherWithParam2<                               \
       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
-      ParamType2, ReturnTypesF> DefineMatcher(const ParamType1 &Param1,        \
-                                              const ParamType2 &Param2) {      \
+      ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1,        \
+                                              ParamType2 const &Param2) {      \
     return internal::PolymorphicMatcherWithParam2<                             \
         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
         ParamType2, ReturnTypesF>(Param1, Param2);                             \
@@ -308,7 +308,7 @@
   typedef internal::PolymorphicMatcherWithParam2<                              \
       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
       ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
-      const ParamType1 &Param1, const ParamType2 &Param2);                     \
+      ParamType1 const &Param1, ParamType2 const &Param2);                     \
   template <typename NodeType, typename ParamT1, typename ParamT2>             \
   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
       NodeType, ParamT1, ParamT2>::matches(                                    \
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index 72ae612..faa9254 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -79,7 +79,7 @@
   /// namedDecl and varDecl are excluded in a FunctionDecl context, because
   /// those matchers would match respectively all or no nodes in such a context.
   static std::vector<MatcherCompletion>
-  getCompletions(llvm::ArrayRef<std::pair<MatcherCtor, unsigned> > Context);
+  getCompletions(ArrayRef<std::pair<MatcherCtor, unsigned> > Context);
 
   /// \brief Construct a matcher from the registry.
   ///
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
index a83cbc5..09c614c 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -238,7 +238,7 @@
       : Arena(A), SelfVar(nullptr), Scfg(nullptr), CurrentBB(nullptr),
         CurrentBlockInfo(nullptr) {
     // FIXME: we don't always have a self-variable.
-    SelfVar = new (Arena) til::Variable();
+    SelfVar = new (Arena) til::Variable(nullptr);
     SelfVar->setKind(til::Variable::VK_SFun);
   }
 
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
index c8784b6..6ebc95d 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyOps.def
+++ b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
@@ -34,7 +34,7 @@
 TIL_OPCODE_DEF(Alloc)
 TIL_OPCODE_DEF(Load)
 TIL_OPCODE_DEF(Store)
-TIL_OPCODE_DEF(ArrayFirst)
+TIL_OPCODE_DEF(ArrayIndex)
 TIL_OPCODE_DEF(ArrayAdd)
 
 TIL_OPCODE_DEF(UnaryOp)
@@ -42,6 +42,7 @@
 TIL_OPCODE_DEF(Cast)
 
 TIL_OPCODE_DEF(SCFG)
+TIL_OPCODE_DEF(BasicBlock)
 TIL_OPCODE_DEF(Phi)
 TIL_OPCODE_DEF(Goto)
 TIL_OPCODE_DEF(Branch)
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
index dcb196f..8e4299e 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -52,6 +52,7 @@
 #include "ThreadSafetyUtil.h"
 
 #include <stdint.h>
+#include <algorithm>
 #include <cassert>
 #include <cstddef>
 #include <utility>
@@ -236,7 +237,7 @@
 
 template<>
 inline ValueType ValueType::getValueType<StringRef>() {
-  return ValueType(BT_Pointer, getSizeType(sizeof(StringRef)), false, 0);
+  return ValueType(BT_String, getSizeType(sizeof(StringRef)), false, 0);
 }
 
 template<>
@@ -246,13 +247,6 @@
 
 
 
-enum TraversalKind {
-  TRV_Normal,
-  TRV_Lazy, // subexpression may need to be traversed lazily
-  TRV_Tail  // subexpression occurs in a tail position
-};
-
-
 // Base class for AST nodes in the typed intermediate language.
 class SExpr {
 public:
@@ -264,8 +258,9 @@
   //   copy constructor: construct copy of E, with some additional arguments.
   // }
   //
-  // template <class V> typename V::R_SExpr traverse(V &Visitor) {
-  //   traverse all subexpressions, following the traversal/rewriter interface
+  // template <class V>
+  // typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+  //   traverse all subexpressions, following the traversal/rewriter interface.
   // }
   //
   // template <class C> typename C::CType compare(CType* E, C& Cmp) {
@@ -370,13 +365,14 @@
   // Let-variable, function parameter, or self-variable
   enum VariableKind {
     VK_Let,
+    VK_LetBB,
     VK_Fun,
     VK_SFun
   };
 
   // These are defined after SExprRef contructor, below
+  inline Variable(SExpr *D, const clang::ValueDecl *Cvd = nullptr);
   inline Variable(StringRef s, SExpr *D = nullptr);
-  inline Variable(SExpr *D = nullptr, const clang::ValueDecl *Cvd = nullptr);
   inline Variable(const Variable &Vd, SExpr *D);
 
   VariableKind kind() const { return static_cast<VariableKind>(Flags); }
@@ -394,6 +390,7 @@
   unsigned getID() const { return Id; }
   unsigned getBlockID() const { return BlockID; }
 
+  void setName(StringRef S) { Name = S; }
   void setID(unsigned Bid, unsigned I) {
     BlockID = static_cast<unsigned short>(Bid);
     Id = static_cast<unsigned short>(I);
@@ -402,9 +399,10 @@
   void setDefinition(SExpr *E);
   void setKind(VariableKind K) { Flags = K; }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
     // This routine is only called for variable references.
-    return Visitor.reduceVariableRef(this);
+    return Vs.reduceVariableRef(this);
   }
 
   template <class C> typename C::CType compare(Variable* E, C& Cmp) {
@@ -474,9 +472,10 @@
     }
   }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
     assert(Result && "Cannot traverse Future that has not been forced.");
-    return Visitor.traverse(Result);
+    return Vs.traverse(Result, Ctx);
   }
 
   template <class C> typename C::CType compare(Future* E, C& Cmp) {
@@ -568,8 +567,9 @@
   Undefined(const clang::Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
   Undefined(const Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    return Visitor.reduceUndefined(*this);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceUndefined(*this);
   }
 
   template <class C> typename C::CType compare(Undefined* E, C& Cmp) {
@@ -589,8 +589,8 @@
   Wildcard() : SExpr(COP_Wildcard) {}
   Wildcard(const Wildcard &W) : SExpr(W) {}
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    return Visitor.reduceWildcard(*this);
+  template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceWildcard(*this);
   }
 
   template <class C> typename C::CType compare(Wildcard* E, C& Cmp) {
@@ -599,15 +599,17 @@
 };
 
 
+template <class T> class LiteralT;
+
 // Base class for literal values.
 class Literal : public SExpr {
 public:
   static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
 
   Literal(const clang::Expr *C)
-     : SExpr(COP_Literal), ValType(ValueType::getValueType<void>())
+     : SExpr(COP_Literal), ValType(ValueType::getValueType<void>()), Cexpr(C)
   { }
-  Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT) {}
+  Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT), Cexpr(nullptr) {}
   Literal(const Literal &L) : SExpr(L), ValType(L.ValType), Cexpr(L.Cexpr) {}
 
   // The clang expression for this literal.
@@ -615,9 +617,14 @@
 
   ValueType valueType() const { return ValType; }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    return Visitor.reduceLiteral(*this);
+  template<class T> const LiteralT<T>& as() const {
+    return *static_cast<const LiteralT<T>*>(this);
   }
+  template<class T> LiteralT<T>& as() {
+    return *static_cast<LiteralT<T>*>(this);
+  }
+
+  template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx);
 
   template <class C> typename C::CType compare(Literal* E, C& Cmp) {
     // TODO -- use value, not pointer equality
@@ -645,6 +652,64 @@
 };
 
 
+
+template <class V>
+typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
+  if (Cexpr)
+    return Vs.reduceLiteral(*this);
+
+  switch (ValType.Base) {
+  case ValueType::BT_Void:
+    break;
+  case ValueType::BT_Bool:
+    return Vs.reduceLiteralT(as<bool>());
+  case ValueType::BT_Int: {
+    switch (ValType.Size) {
+    case ValueType::ST_8:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int8_t>());
+      else
+        return Vs.reduceLiteralT(as<uint8_t>());
+    case ValueType::ST_16:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int16_t>());
+      else
+        return Vs.reduceLiteralT(as<uint16_t>());
+    case ValueType::ST_32:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int32_t>());
+      else
+        return Vs.reduceLiteralT(as<uint32_t>());
+    case ValueType::ST_64:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int64_t>());
+      else
+        return Vs.reduceLiteralT(as<uint64_t>());
+    default:
+      break;
+    }
+  }
+  case ValueType::BT_Float: {
+    switch (ValType.Size) {
+    case ValueType::ST_32:
+      return Vs.reduceLiteralT(as<float>());
+    case ValueType::ST_64:
+      return Vs.reduceLiteralT(as<double>());
+    default:
+      break;
+    }
+  }
+  case ValueType::BT_String:
+    return Vs.reduceLiteralT(as<StringRef>());
+  case ValueType::BT_Pointer:
+    return Vs.reduceLiteralT(as<void*>());
+  case ValueType::BT_ValueRef:
+    break;
+  }
+  return Vs.reduceLiteral(*this);
+}
+
+
 // Literal pointer to an object allocated in memory.
 // At compile time, pointer literals are represented by symbolic names.
 class LiteralPtr : public SExpr {
@@ -657,8 +722,9 @@
   // The clang declaration for the value that this pointer points to.
   const clang::ValueDecl *clangDecl() const { return Cvdecl; }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    return Visitor.reduceLiteralPtr(*this);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceLiteralPtr(*this);
   }
 
   template <class C> typename C::CType compare(LiteralPtr* E, C& Cmp) {
@@ -692,14 +758,15 @@
   SExpr *body() { return Body.get(); }
   const SExpr *body() const { return Body.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
     // This is a variable declaration, so traverse the definition.
-    typename V::R_SExpr E0 = Visitor.traverse(VarDecl->Definition, TRV_Lazy);
+    auto E0 = Vs.traverse(VarDecl->Definition, Vs.typeCtx(Ctx));
     // Tell the rewriter to enter the scope of the function.
-    Variable *Nvd = Visitor.enterScope(*VarDecl, E0);
-    typename V::R_SExpr E1 = Visitor.traverse(Body);
-    Visitor.exitScope(*VarDecl);
-    return Visitor.reduceFunction(*this, Nvd, E1);
+    Variable *Nvd = Vs.enterScope(*VarDecl, E0);
+    auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
+    Vs.exitScope(*VarDecl);
+    return Vs.reduceFunction(*this, Nvd, E1);
   }
 
   template <class C> typename C::CType compare(Function* E, C& Cmp) {
@@ -745,15 +812,16 @@
   SExpr *body() { return Body.get(); }
   const SExpr *body() const { return Body.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
     // A self-variable points to the SFunction itself.
     // A rewrite must introduce the variable with a null definition, and update
     // it after 'this' has been rewritten.
-    Variable *Nvd = Visitor.enterScope(*VarDecl, nullptr /* def */);
-    typename V::R_SExpr E1 = Visitor.traverse(Body);
-    Visitor.exitScope(*VarDecl);
+    Variable *Nvd = Vs.enterScope(*VarDecl, nullptr);
+    auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
+    Vs.exitScope(*VarDecl);
     // A rewrite operation will call SFun constructor to set Vvd->Definition.
-    return Visitor.reduceSFunction(*this, Nvd, E1);
+    return Vs.reduceSFunction(*this, Nvd, E1);
   }
 
   template <class C> typename C::CType compare(SFunction* E, C& Cmp) {
@@ -784,10 +852,11 @@
   SExpr *body() { return Body.get(); }
   const SExpr *body() const { return Body.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nt = Visitor.traverse(ReturnType, TRV_Lazy);
-    typename V::R_SExpr Nb = Visitor.traverse(Body, TRV_Lazy);
-    return Visitor.reduceCode(*this, Nt, Nb);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nt = Vs.traverse(ReturnType, Vs.typeCtx(Ctx));
+    auto Nb = Vs.traverse(Body,       Vs.lazyCtx(Ctx));
+    return Vs.reduceCode(*this, Nt, Nb);
   }
 
   template <class C> typename C::CType compare(Code* E, C& Cmp) {
@@ -818,10 +887,11 @@
   SExpr *body() { return Body.get(); }
   const SExpr *body() const { return Body.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nr = Visitor.traverse(Range, TRV_Lazy);
-    typename V::R_SExpr Nb = Visitor.traverse(Body,  TRV_Lazy);
-    return Visitor.reduceField(*this, Nr, Nb);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nr = Vs.traverse(Range, Vs.typeCtx(Ctx));
+    auto Nb = Vs.traverse(Body,  Vs.lazyCtx(Ctx));
+    return Vs.reduceField(*this, Nr, Nb);
   }
 
   template <class C> typename C::CType compare(Field* E, C& Cmp) {
@@ -853,10 +923,11 @@
   SExpr *arg() { return Arg.get(); }
   const SExpr *arg() const { return Arg.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nf = Visitor.traverse(Fun);
-    typename V::R_SExpr Na = Visitor.traverse(Arg);
-    return Visitor.reduceApply(*this, Nf, Na);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nf = Vs.traverse(Fun, Vs.subExprCtx(Ctx));
+    auto Na = Vs.traverse(Arg, Vs.subExprCtx(Ctx));
+    return Vs.reduceApply(*this, Nf, Na);
   }
 
   template <class C> typename C::CType compare(Apply* E, C& Cmp) {
@@ -889,10 +960,12 @@
 
   bool isDelegation() const { return Arg == nullptr; }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nf = Visitor.traverse(Sfun);
-    typename V::R_SExpr Na = Arg.get() ? Visitor.traverse(Arg) : nullptr;
-    return Visitor.reduceSApply(*this, Nf, Na);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nf = Vs.traverse(Sfun, Vs.subExprCtx(Ctx));
+    typename V::R_SExpr Na = Arg.get() ? Vs.traverse(Arg, Vs.subExprCtx(Ctx))
+                                       : nullptr;
+    return Vs.reduceSApply(*this, Nf, Na);
   }
 
   template <class C> typename C::CType compare(SApply* E, C& Cmp) {
@@ -935,9 +1008,10 @@
       return SlotName;
   }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nr = Visitor.traverse(Rec);
-    return Visitor.reduceProject(*this, Nr);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nr = Vs.traverse(Rec, Vs.subExprCtx(Ctx));
+    return Vs.reduceProject(*this, Nr);
   }
 
   template <class C> typename C::CType compare(Project* E, C& Cmp) {
@@ -968,9 +1042,10 @@
 
   const clang::CallExpr *clangCallExpr() const { return Cexpr; }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nt = Visitor.traverse(Target);
-    return Visitor.reduceCall(*this, Nt);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nt = Vs.traverse(Target, Vs.subExprCtx(Ctx));
+    return Vs.reduceCall(*this, Nt);
   }
 
   template <class C> typename C::CType compare(Call* E, C& Cmp) {
@@ -1001,9 +1076,10 @@
   SExpr *dataType() { return Dtype.get(); }
   const SExpr *dataType() const { return Dtype.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nd = Visitor.traverse(Dtype);
-    return Visitor.reduceAlloc(*this, Nd);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nd = Vs.traverse(Dtype, Vs.declCtx(Ctx));
+    return Vs.reduceAlloc(*this, Nd);
   }
 
   template <class C> typename C::CType compare(Alloc* E, C& Cmp) {
@@ -1029,9 +1105,10 @@
   SExpr *pointer() { return Ptr.get(); }
   const SExpr *pointer() const { return Ptr.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Np = Visitor.traverse(Ptr);
-    return Visitor.reduceLoad(*this, Np);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Np = Vs.traverse(Ptr, Vs.subExprCtx(Ctx));
+    return Vs.reduceLoad(*this, Np);
   }
 
   template <class C> typename C::CType compare(Load* E, C& Cmp) {
@@ -1058,10 +1135,11 @@
   SExpr *source() { return Source.get(); }     // Value to store
   const SExpr *source() const { return Source.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Np = Visitor.traverse(Dest);
-    typename V::R_SExpr Nv = Visitor.traverse(Source);
-    return Visitor.reduceStore(*this, Np, Nv);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Np = Vs.traverse(Dest,   Vs.subExprCtx(Ctx));
+    auto Nv = Vs.traverse(Source, Vs.subExprCtx(Ctx));
+    return Vs.reduceStore(*this, Np, Nv);
   }
 
   template <class C> typename C::CType compare(Store* E, C& Cmp) {
@@ -1079,27 +1157,37 @@
 
 // If p is a reference to an array, then first(p) is a reference to the first
 // element.  The usual array notation p[i]  becomes first(p + i).
-class ArrayFirst : public SExpr {
+class ArrayIndex : public SExpr {
 public:
-  static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayFirst; }
+  static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayIndex; }
 
-  ArrayFirst(SExpr *A) : SExpr(COP_ArrayFirst), Array(A) {}
-  ArrayFirst(const ArrayFirst &E, SExpr *A) : SExpr(E), Array(A) {}
+  ArrayIndex(SExpr *A, SExpr *N) : SExpr(COP_ArrayIndex), Array(A), Index(N) {}
+  ArrayIndex(const ArrayIndex &E, SExpr *A, SExpr *N)
+    : SExpr(E), Array(A), Index(N) {}
 
   SExpr *array() { return Array.get(); }
   const SExpr *array() const { return Array.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Na = Visitor.traverse(Array);
-    return Visitor.reduceArrayFirst(*this, Na);
+  SExpr *index() { return Index.get(); }
+  const SExpr *index() const { return Index.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
+    auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
+    return Vs.reduceArrayIndex(*this, Na, Ni);
   }
 
-  template <class C> typename C::CType compare(ArrayFirst* E, C& Cmp) {
-    return Cmp.compare(array(), E->array());
+  template <class C> typename C::CType compare(ArrayIndex* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(array(), E->array());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(index(), E->index());
   }
 
 private:
   SExprRef Array;
+  SExprRef Index;
 };
 
 
@@ -1120,10 +1208,11 @@
   SExpr *index() { return Index.get(); }
   const SExpr *index() const { return Index.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Na = Visitor.traverse(Array);
-    typename V::R_SExpr Ni = Visitor.traverse(Index);
-    return Visitor.reduceArrayAdd(*this, Na, Ni);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
+    auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
+    return Vs.reduceArrayAdd(*this, Na, Ni);
   }
 
   template <class C> typename C::CType compare(ArrayAdd* E, C& Cmp) {
@@ -1156,9 +1245,10 @@
   SExpr *expr() { return Expr0.get(); }
   const SExpr *expr() const { return Expr0.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Ne = Visitor.traverse(Expr0);
-    return Visitor.reduceUnaryOp(*this, Ne);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    return Vs.reduceUnaryOp(*this, Ne);
   }
 
   template <class C> typename C::CType compare(UnaryOp* E, C& Cmp) {
@@ -1198,10 +1288,11 @@
   SExpr *expr1() { return Expr1.get(); }
   const SExpr *expr1() const { return Expr1.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Ne0 = Visitor.traverse(Expr0);
-    typename V::R_SExpr Ne1 = Visitor.traverse(Expr1);
-    return Visitor.reduceBinaryOp(*this, Ne0, Ne1);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne0 = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    auto Ne1 = Vs.traverse(Expr1, Vs.subExprCtx(Ctx));
+    return Vs.reduceBinaryOp(*this, Ne0, Ne1);
   }
 
   template <class C> typename C::CType compare(BinaryOp* E, C& Cmp) {
@@ -1236,9 +1327,10 @@
   SExpr *expr() { return Expr0.get(); }
   const SExpr *expr() const { return Expr0.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Ne = Visitor.traverse(Expr0);
-    return Visitor.reduceCast(*this, Ne);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    return Vs.reduceCast(*this, Ne);
   }
 
   template <class C> typename C::CType compare(Cast* E, C& Cmp) {
@@ -1254,8 +1346,183 @@
 };
 
 
+class SCFG;
 
-class BasicBlock;
+
+class Phi : public SExpr {
+public:
+  // TODO: change to SExprRef
+  typedef SimpleArray<SExpr *> ValArray;
+
+  // In minimal SSA form, all Phi nodes are MultiVal.
+  // During conversion to SSA, incomplete Phi nodes may be introduced, which
+  // are later determined to be SingleVal, and are thus redundant.
+  enum Status {
+    PH_MultiVal = 0, // Phi node has multiple distinct values.  (Normal)
+    PH_SingleVal,    // Phi node has one distinct value, and can be eliminated
+    PH_Incomplete    // Phi node is incomplete
+  };
+
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
+
+  Phi() : SExpr(COP_Phi) {}
+  Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {}
+  Phi(const Phi &P, ValArray &&Vs)    : SExpr(P), Values(std::move(Vs)) {}
+
+  const ValArray &values() const { return Values; }
+  ValArray &values() { return Values; }
+
+  Status status() const { return static_cast<Status>(Flags); }
+  void setStatus(Status s) { Flags = s; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    typename V::template Container<typename V::R_SExpr>
+      Nvs(Vs, Values.size());
+
+    for (auto *Val : Values) {
+      Nvs.push_back( Vs.traverse(Val, Vs.subExprCtx(Ctx)) );
+    }
+    return Vs.reducePhi(*this, Nvs);
+  }
+
+  template <class C> typename C::CType compare(Phi *E, C &Cmp) {
+    // TODO: implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  ValArray Values;
+};
+
+
+// A basic block is part of an SCFG, and can be treated as a function in
+// continuation passing style.  It consists of a sequence of phi nodes, which
+// are "arguments" to the function, followed by a sequence of instructions.
+// Both arguments and instructions define new variables.  It ends with a
+// branch or goto to another basic block in the same SCFG.
+class BasicBlock : public SExpr {
+public:
+  typedef SimpleArray<Variable*>   VarArray;
+  typedef SimpleArray<BasicBlock*> BlockArray;
+
+  static bool classof(const SExpr *E) { return E->opcode() == COP_BasicBlock; }
+
+  explicit BasicBlock(MemRegionRef A, BasicBlock* P = nullptr)
+      : SExpr(COP_BasicBlock), Arena(A), CFGPtr(nullptr), BlockID(0),
+        Parent(P), Terminator(nullptr)
+  { }
+  BasicBlock(BasicBlock &B, VarArray &&As, VarArray &&Is, SExpr *T)
+      : SExpr(COP_BasicBlock), Arena(B.Arena), CFGPtr(nullptr), BlockID(0),
+        Parent(nullptr), Args(std::move(As)), Instrs(std::move(Is)),
+        Terminator(T)
+  { }
+
+  unsigned blockID() const { return BlockID; }
+  unsigned numPredecessors() const { return Predecessors.size(); }
+
+  const SCFG* cfg() const { return CFGPtr; }
+  SCFG* cfg() { return CFGPtr; }
+
+  const BasicBlock *parent() const { return Parent; }
+  BasicBlock *parent() { return Parent; }
+
+  const VarArray &arguments() const { return Args; }
+  VarArray &arguments() { return Args; }
+
+  const VarArray &instructions() const { return Instrs; }
+  VarArray &instructions() { return Instrs; }
+
+  const BlockArray &predecessors() const { return Predecessors; }
+  BlockArray &predecessors() { return Predecessors; }
+
+  const SExpr *terminator() const { return Terminator.get(); }
+  SExpr *terminator() { return Terminator.get(); }
+
+  void setBlockID(unsigned i)   { BlockID = i; }
+  void setParent(BasicBlock *P) { Parent = P;  }
+  void setTerminator(SExpr *E)  { Terminator.reset(E); }
+
+  // Add a new argument.  V must define a phi-node.
+  void addArgument(Variable *V) {
+    V->setKind(Variable::VK_LetBB);
+    Args.reserveCheck(1, Arena);
+    Args.push_back(V);
+  }
+  // Add a new instruction.
+  void addInstruction(Variable *V) {
+    V->setKind(Variable::VK_LetBB);
+    Instrs.reserveCheck(1, Arena);
+    Instrs.push_back(V);
+  }
+  // Add a new predecessor, and return the phi-node index for it.
+  // Will add an argument to all phi-nodes, initialized to nullptr.
+  unsigned addPredecessor(BasicBlock *Pred);
+
+  // Reserve space for Nargs arguments.
+  void reserveArguments(unsigned Nargs)   { Args.reserve(Nargs, Arena); }
+
+  // Reserve space for Nins instructions.
+  void reserveInstructions(unsigned Nins) { Instrs.reserve(Nins, Arena); }
+
+  // Reserve space for NumPreds predecessors, including space in phi nodes.
+  void reservePredecessors(unsigned NumPreds);
+
+  // Return the index of BB, or Predecessors.size if BB is not a predecessor.
+  unsigned findPredecessorIndex(const BasicBlock *BB) const {
+    auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB);
+    return std::distance(Predecessors.cbegin(), I);
+  }
+
+  // Set id numbers for variables.
+  void renumberVars();
+
+  template <class V>
+  typename V::R_BasicBlock traverse(V &Vs, typename V::R_Ctx Ctx) {
+    typename V::template Container<Variable*> Nas(Vs, Args.size());
+    typename V::template Container<Variable*> Nis(Vs, Instrs.size());
+
+    // Entering the basic block should do any scope initialization.
+    Vs.enterBasicBlock(*this);
+
+    for (auto *A : Args) {
+      auto Ne = Vs.traverse(A->Definition, Vs.subExprCtx(Ctx));
+      Variable *Nvd = Vs.enterScope(*A, Ne);
+      Nas.push_back(Nvd);
+    }
+    for (auto *I : Instrs) {
+      auto Ne = Vs.traverse(I->Definition, Vs.subExprCtx(Ctx));
+      Variable *Nvd = Vs.enterScope(*I, Ne);
+      Nis.push_back(Nvd);
+    }
+    auto Nt = Vs.traverse(Terminator, Ctx);
+
+    // Exiting the basic block should handle any scope cleanup.
+    Vs.exitBasicBlock(*this);
+
+    return Vs.reduceBasicBlock(*this, Nas, Nis, Nt);
+  }
+
+  template <class C> typename C::CType compare(BasicBlock *E, C &Cmp) {
+    // TODO: implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  friend class SCFG;
+
+  MemRegionRef Arena;
+
+  SCFG       *CFGPtr;       // The CFG that contains this block.
+  unsigned   BlockID;       // unique id for this BB in the containing CFG
+  BasicBlock *Parent;       // The parent block is the enclosing lexical scope.
+                            // The parent dominates this block.
+  BlockArray Predecessors;  // Predecessor blocks in the CFG.
+  VarArray   Args;          // Phi nodes.  One argument per predecessor.
+  VarArray   Instrs;        // Instructions.
+  SExprRef   Terminator;    // Branch or Goto
+};
+
 
 // An SCFG is a control-flow graph.  It consists of a set of basic blocks, each
 // of which terminates in a branch to another basic block.  There is one
@@ -1269,10 +1536,18 @@
   static bool classof(const SExpr *E) { return E->opcode() == COP_SCFG; }
 
   SCFG(MemRegionRef A, unsigned Nblocks)
-      : SExpr(COP_SCFG), Blocks(A, Nblocks),
-        Entry(nullptr), Exit(nullptr) {}
+    : SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks),
+      Entry(nullptr), Exit(nullptr) {
+    Entry = new (A) BasicBlock(A, nullptr);
+    Exit  = new (A) BasicBlock(A, Entry);
+    auto *V = new (A) Variable(new (A) Phi());
+    Exit->addArgument(V);
+    add(Entry);
+    add(Exit);
+  }
   SCFG(const SCFG &Cfg, BlockArray &&Ba) // steals memory from Ba
-      : SExpr(COP_SCFG), Blocks(std::move(Ba)), Entry(nullptr), Exit(nullptr) {
+      : SExpr(COP_SCFG), Arena(Cfg.Arena), Blocks(std::move(Ba)),
+        Entry(nullptr), Exit(nullptr) {
     // TODO: set entry and exit!
   }
 
@@ -1290,11 +1565,30 @@
   const BasicBlock *exit() const { return Exit; }
   BasicBlock *exit() { return Exit; }
 
-  void add(BasicBlock *BB);
-  void setEntry(BasicBlock *BB) { Entry = BB; }
-  void setExit(BasicBlock *BB) { Exit = BB; }
+  inline void add(BasicBlock *BB) {
+    assert(BB->CFGPtr == nullptr || BB->CFGPtr == this);
+    BB->setBlockID(Blocks.size());
+    BB->CFGPtr = this;
+    Blocks.reserveCheck(1, Arena);
+    Blocks.push_back(BB);
+  }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor);
+  void setEntry(BasicBlock *BB) { Entry = BB; }
+  void setExit(BasicBlock *BB)  { Exit = BB;  }
+
+  // Set varable ids in all blocks.
+  void renumberVars();
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    Vs.enterCFG(*this);
+    typename V::template Container<BasicBlock *> Bbs(Vs, Blocks.size());
+    for (auto *B : Blocks) {
+      Bbs.push_back( B->traverse(Vs, Vs.subExprCtx(Ctx)) );
+    }
+    Vs.exitCFG(*this);
+    return Vs.reduceSCFG(*this, Bbs);
+  }
 
   template <class C> typename C::CType compare(SCFG *E, C &Cmp) {
     // TODO -- implement CFG comparisons
@@ -1302,166 +1596,10 @@
   }
 
 private:
-  BlockArray Blocks;
-  BasicBlock *Entry;
-  BasicBlock *Exit;
-};
-
-
-// A basic block is part of an SCFG, and can be treated as a function in
-// continuation passing style.  It consists of a sequence of phi nodes, which
-// are "arguments" to the function, followed by a sequence of instructions.
-// Both arguments and instructions define new variables.  It ends with a
-// branch or goto to another basic block in the same SCFG.
-class BasicBlock {
-public:
-  typedef SimpleArray<Variable*> VarArray;
-
-  BasicBlock(MemRegionRef A, unsigned Nargs, unsigned Nins,
-             SExpr *Term = nullptr)
-      : BlockID(0), NumVars(0), NumPredecessors(0), Parent(nullptr),
-        Args(A, Nargs), Instrs(A, Nins), Terminator(Term) {}
-  BasicBlock(const BasicBlock &B, VarArray &&As, VarArray &&Is, SExpr *T)
-      : BlockID(0),  NumVars(B.NumVars), NumPredecessors(B.NumPredecessors),
-        Parent(nullptr), Args(std::move(As)), Instrs(std::move(Is)),
-        Terminator(T) {}
-
-  unsigned blockID() const { return BlockID; }
-  unsigned numPredecessors() const { return NumPredecessors; }
-
-  const BasicBlock *parent() const { return Parent; }
-  BasicBlock *parent() { return Parent; }
-
-  const VarArray &arguments() const { return Args; }
-  VarArray &arguments() { return Args; }
-
-  const VarArray &instructions() const { return Instrs; }
-  VarArray &instructions() { return Instrs; }
-
-  const SExpr *terminator() const { return Terminator.get(); }
-  SExpr *terminator() { return Terminator.get(); }
-
-  void setBlockID(unsigned i) { BlockID = i; }
-  void setParent(BasicBlock *P) { Parent = P; }
-  void setNumPredecessors(unsigned NP) { NumPredecessors = NP; }
-  void setTerminator(SExpr *E) { Terminator.reset(E); }
-
-  void addArgument(Variable *V) {
-    V->setID(BlockID, NumVars++);
-    Args.push_back(V);
-  }
-  void addInstruction(Variable *V) {
-    V->setID(BlockID, NumVars++);
-    Instrs.push_back(V);
-  }
-
-  template <class V> BasicBlock *traverse(V &Visitor) {
-    typename V::template Container<Variable*> Nas(Visitor, Args.size());
-    typename V::template Container<Variable*> Nis(Visitor, Instrs.size());
-
-    for (auto *A : Args) {
-      typename V::R_SExpr Ne = Visitor.traverse(A->Definition);
-      Variable *Nvd = Visitor.enterScope(*A, Ne);
-      Nas.push_back(Nvd);
-    }
-    for (auto *I : Instrs) {
-      typename V::R_SExpr Ne = Visitor.traverse(I->Definition);
-      Variable *Nvd = Visitor.enterScope(*I, Ne);
-      Nis.push_back(Nvd);
-    }
-    typename V::R_SExpr Nt = Visitor.traverse(Terminator);
-
-    // TODO: use reverse iterator
-    for (unsigned J = 0, JN = Instrs.size(); J < JN; ++J)
-      Visitor.exitScope(*Instrs[JN-J]);
-    for (unsigned I = 0, IN = Instrs.size(); I < IN; ++I)
-      Visitor.exitScope(*Args[IN-I]);
-
-    return Visitor.reduceBasicBlock(*this, Nas, Nis, Nt);
-  }
-
-  template <class C> typename C::CType compare(BasicBlock *E, C &Cmp) {
-    // TODO: implement CFG comparisons
-    return Cmp.comparePointers(this, E);
-  }
-
-private:
-  friend class SCFG;
-
-  unsigned BlockID;
-  unsigned NumVars;
-  unsigned NumPredecessors; // Number of blocks which jump to this one.
-
-  BasicBlock *Parent;       // The parent block is the enclosing lexical scope.
-                            // The parent dominates this block.
-  VarArray Args;            // Phi nodes.  One argument per predecessor.
-  VarArray Instrs;
-  SExprRef Terminator;
-};
-
-
-inline void SCFG::add(BasicBlock *BB) {
-  BB->setBlockID(Blocks.size());
-  Blocks.push_back(BB);
-}
-
-
-template <class V>
-typename V::R_SExpr SCFG::traverse(V &Visitor) {
-  Visitor.enterCFG(*this);
-  typename V::template Container<BasicBlock *> Bbs(Visitor, Blocks.size());
-  for (auto *B : Blocks) {
-    BasicBlock *Nbb = B->traverse(Visitor);
-    Bbs.push_back(Nbb);
-  }
-  Visitor.exitCFG(*this);
-  return Visitor.reduceSCFG(*this, Bbs);
-}
-
-
-class Phi : public SExpr {
-public:
-  // TODO: change to SExprRef
-  typedef SimpleArray<SExpr *> ValArray;
-
-  // In minimal SSA form, all Phi nodes are MultiVal.
-  // During conversion to SSA, incomplete Phi nodes may be introduced, which
-  // are later determined to be SingleVal.
-  enum Status {
-    PH_MultiVal = 0, // Phi node has multiple distinct values.  (Normal)
-    PH_SingleVal,    // Phi node has one distinct value, and can be eliminated
-    PH_Incomplete    // Phi node is incomplete
-  };
-
-  static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
-
-  Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {}
-  Phi(const Phi &P, ValArray &&Vs) // steals memory of Vs
-      : SExpr(COP_Phi), Values(std::move(Vs)) {}
-
-  const ValArray &values() const { return Values; }
-  ValArray &values() { return Values; }
-
-  Status status() const { return static_cast<Status>(Flags); }
-  void setStatus(Status s) { Flags = s; }
-
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::template Container<typename V::R_SExpr> Nvs(Visitor,
-                                                            Values.size());
-    for (auto *Val : Values) {
-      typename V::R_SExpr Nv = Visitor.traverse(Val);
-      Nvs.push_back(Nv);
-    }
-    return Visitor.reducePhi(*this, Nvs);
-  }
-
-  template <class C> typename C::CType compare(Phi *E, C &Cmp) {
-    // TODO: implement CFG comparisons
-    return Cmp.comparePointers(this, E);
-  }
-
-private:
-  ValArray Values;
+  MemRegionRef Arena;
+  BlockArray   Blocks;
+  BasicBlock   *Entry;
+  BasicBlock   *Exit;
 };
 
 
@@ -1469,8 +1607,8 @@
 public:
   static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
 
-  Goto(BasicBlock *B, unsigned Index)
-      : SExpr(COP_Goto), TargetBlock(B), Index(0) {}
+  Goto(BasicBlock *B, unsigned I)
+      : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
   Goto(const Goto &G, BasicBlock *B, unsigned I)
       : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
 
@@ -1479,10 +1617,10 @@
 
   unsigned index() const { return Index; }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    // TODO -- rewrite indices properly
-    BasicBlock *Ntb = Visitor.reduceBasicBlockRef(TargetBlock);
-    return Visitor.reduceGoto(*this, Ntb, Index);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    BasicBlock *Ntb = Vs.reduceBasicBlockRef(TargetBlock);
+    return Vs.reduceGoto(*this, Ntb);
   }
 
   template <class C> typename C::CType compare(Goto *E, C &Cmp) {
@@ -1500,13 +1638,14 @@
 public:
   static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
 
-  Branch(SExpr *C, BasicBlock *T, BasicBlock *E)
+  Branch(SExpr *C, BasicBlock *T, BasicBlock *E, unsigned TI, unsigned EI)
       : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
-        ThenIndex(0), ElseIndex(0)
+        ThenIndex(TI), ElseIndex(EI)
   {}
-  Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E)
+  Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E,
+         unsigned TI, unsigned EI)
       : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
-        ThenIndex(0), ElseIndex(0)
+        ThenIndex(TI), ElseIndex(EI)
   {}
 
   const SExpr *condition() const { return Condition; }
@@ -1521,11 +1660,12 @@
   unsigned thenIndex() const { return ThenIndex; }
   unsigned elseIndex() const { return ElseIndex; }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nc = Visitor.traverse(Condition);
-    BasicBlock *Ntb = Visitor.reduceBasicBlockRef(ThenBlock);
-    BasicBlock *Nte = Visitor.reduceBasicBlockRef(ElseBlock);
-    return Visitor.reduceBranch(*this, Nc, Ntb, Nte);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
+    BasicBlock *Ntb = Vs.reduceBasicBlockRef(ThenBlock);
+    BasicBlock *Nte = Vs.reduceBasicBlockRef(ElseBlock);
+    return Vs.reduceBranch(*this, Nc, Ntb, Nte);
   }
 
   template <class C> typename C::CType compare(Branch *E, C &Cmp) {
@@ -1553,8 +1693,9 @@
 
   StringRef name() const { return Name; }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    return Visitor.reduceIdentifier(*this);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceIdentifier(*this);
   }
 
   template <class C> typename C::CType compare(Identifier* E, C& Cmp) {
@@ -1567,7 +1708,7 @@
 
 
 // An if-then-else expression.
-// This is a pseduo-term; it will be lowered to a CFG.
+// This is a pseduo-term; it will be lowered to a branch in a CFG.
 class IfThenElse : public SExpr {
 public:
   static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; }
@@ -1588,11 +1729,12 @@
   SExpr *elseExpr() { return ElseExpr.get(); }     // Value to store
   const SExpr *elseExpr() const { return ElseExpr.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
-    typename V::R_SExpr Nc = Visitor.traverse(Condition);
-    typename V::R_SExpr Nt = Visitor.traverse(ThenExpr);
-    typename V::R_SExpr Ne = Visitor.traverse(ElseExpr);
-    return Visitor.reduceIfThenElse(*this, Nc, Nt, Ne);
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
+    auto Nt = Vs.traverse(ThenExpr,  Vs.subExprCtx(Ctx));
+    auto Ne = Vs.traverse(ElseExpr,  Vs.subExprCtx(Ctx));
+    return Vs.reduceIfThenElse(*this, Nc, Nt, Ne);
   }
 
   template <class C> typename C::CType compare(IfThenElse* E, C& Cmp) {
@@ -1613,7 +1755,7 @@
 
 
 // A let-expression,  e.g.  let x=t; u.
-// This is a pseduo-term; it will be lowered to a CFG.
+// This is a pseduo-term; it will be lowered to instructions in a CFG.
 class Let : public SExpr {
 public:
   static bool classof(const SExpr *E) { return E->opcode() == COP_Let; }
@@ -1631,14 +1773,15 @@
   SExpr *body() { return Body.get(); }
   const SExpr *body() const { return Body.get(); }
 
-  template <class V> typename V::R_SExpr traverse(V &Visitor) {
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
     // This is a variable declaration, so traverse the definition.
-    typename V::R_SExpr E0 = Visitor.traverse(VarDecl->Definition, TRV_Lazy);
+    auto E0 = Vs.traverse(VarDecl->Definition, Vs.subExprCtx(Ctx));
     // Tell the rewriter to enter the scope of the let variable.
-    Variable *Nvd = Visitor.enterScope(*VarDecl, E0);
-    typename V::R_SExpr E1 = Visitor.traverse(Body);
-    Visitor.exitScope(*VarDecl);
-    return Visitor.reduceLet(*this, Nvd, E1);
+    Variable *Nvd = Vs.enterScope(*VarDecl, E0);
+    auto E1 = Vs.traverse(Body, Ctx);
+    Vs.exitScope(*VarDecl);
+    return Vs.reduceLet(*this, Nvd, E1);
   }
 
   template <class C> typename C::CType compare(Let* E, C& Cmp) {
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
index b28085b..bc1490b 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -45,33 +45,31 @@
 //       compute a result for a node of type X
 //
 // The reduceX methods control the kind of traversal (visitor, copy, etc.).
-// These are separated into a separate class R for the purpose of code reuse.
-// The full reducer interface also has methods to handle scopes
-template <class Self, class R> class Traversal : public R {
+// They are defined in derived classes.
+//
+// Class R defines the basic interface types (R_SExpr).
+template <class Self, class R>
+class Traversal {
 public:
-  Self *self() { return reinterpret_cast<Self *>(this); }
+  Self *self() { return static_cast<Self *>(this); }
 
   // Traverse an expression -- returning a result of type R_SExpr.
   // Override this method to do something for every expression, regardless
-  // of which kind it is.  TraversalKind indicates the context in which
-  // the expression occurs, and can be:
-  //   TRV_Normal
-  //   TRV_Lazy   -- e may need to be traversed lazily, using a Future.
-  //   TRV_Tail   -- e occurs in a tail position
-  typename R::R_SExpr traverse(SExprRef &E, TraversalKind K = TRV_Normal) {
-    return traverse(E.get(), K);
+  // of which kind it is.
+  typename R::R_SExpr traverse(SExprRef &E, typename R::R_Ctx Ctx) {
+    return traverse(E.get(), Ctx);
   }
 
-  typename R::R_SExpr traverse(SExpr *E, TraversalKind K = TRV_Normal) {
-    return traverseByCase(E);
+  typename R::R_SExpr traverse(SExpr *E, typename R::R_Ctx Ctx) {
+    return traverseByCase(E, Ctx);
   }
 
   // Helper method to call traverseX(e) on the appropriate type.
-  typename R::R_SExpr traverseByCase(SExpr *E) {
+  typename R::R_SExpr traverseByCase(SExpr *E, typename R::R_Ctx Ctx) {
     switch (E->opcode()) {
 #define TIL_OPCODE_DEF(X)                                                   \
     case COP_##X:                                                           \
-      return self()->traverse##X(cast<X>(E));
+      return self()->traverse##X(cast<X>(E), Ctx);
 #include "ThreadSafetyOps.def"
 #undef TIL_OPCODE_DEF
     }
@@ -80,41 +78,83 @@
 // Traverse e, by static dispatch on the type "X" of e.
 // Override these methods to do something for a particular kind of term.
 #define TIL_OPCODE_DEF(X)                                                   \
-  typename R::R_SExpr traverse##X(X *e) { return e->traverse(*self()); }
+  typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) {            \
+    return e->traverse(*self(), Ctx);                                       \
+  }
 #include "ThreadSafetyOps.def"
 #undef TIL_OPCODE_DEF
 };
 
 
-// Implements a Reducer that makes a deep copy of an SExpr.
-// The default behavior of reduce##X(...) is to create a copy of the original.
-// Subclasses can override reduce##X to implement non-destructive rewriting
-// passes.
-class CopyReducer {
+// Base class for simple reducers that don't much care about the context.
+class SimpleReducerBase {
 public:
-  CopyReducer() {}
+  enum TraversalKind {
+    TRV_Normal,
+    TRV_Decl,
+    TRV_Lazy,
+    TRV_Type
+  };
 
-  void setArena(MemRegionRef A) { Arena = A; }
+  // R_Ctx defines a "context" for the traversal, which encodes information
+  // about where a term appears.  This can be used to encoding the
+  // "current continuation" for CPS transforms, or other information.
+  typedef TraversalKind R_Ctx;
 
+  // Create context for an ordinary subexpression.
+  R_Ctx subExprCtx(R_Ctx Ctx) { return TRV_Normal; }
+
+  // Create context for a subexpression that occurs in a declaration position
+  // (e.g. function body).
+  R_Ctx declCtx(R_Ctx Ctx) { return TRV_Decl; }
+
+  // Create context for a subexpression that occurs in a position that
+  // should be reduced lazily.  (e.g. code body).
+  R_Ctx lazyCtx(R_Ctx Ctx) { return TRV_Lazy; }
+
+  // Create context for a subexpression that occurs in a type position.
+  R_Ctx typeCtx(R_Ctx Ctx) { return TRV_Type; }
+};
+
+
+// Base class for traversals that rewrite an SExpr to another SExpr.
+class CopyReducerBase : public SimpleReducerBase {
+public:
   // R_SExpr is the result type for a traversal.
   // A copy or non-destructive rewrite returns a newly allocated term.
   typedef SExpr *R_SExpr;
+  typedef BasicBlock *R_BasicBlock;
 
   // Container is a minimal interface used to store results when traversing
   // SExprs of variable arity, such as Phi, Goto, and SCFG.
   template <class T> class Container {
   public:
     // Allocate a new container with a capacity for n elements.
-    Container(CopyReducer &R, unsigned N) : Elems(R.Arena, N) {}
+    Container(CopyReducerBase &S, unsigned N) : Elems(S.Arena, N) {}
 
     // Push a new element onto the container.
     void push_back(T E) { Elems.push_back(E); }
 
-  private:
-    friend class CopyReducer;
     SimpleArray<T> Elems;
   };
 
+  CopyReducerBase(MemRegionRef A) : Arena(A) {}
+
+protected:
+  MemRegionRef Arena;
+};
+
+
+// Implements a traversal that makes a deep copy of an SExpr.
+// The default behavior of reduce##X(...) is to create a copy of the original.
+// Subclasses can override reduce##X to implement non-destructive rewriting
+// passes.
+template<class Self>
+class CopyReducer : public Traversal<Self, CopyReducerBase>,
+                    public CopyReducerBase {
+public:
+  CopyReducer(MemRegionRef A) : CopyReducerBase(A) {}
+
 public:
   R_SExpr reduceNull() {
     return nullptr;
@@ -131,6 +171,10 @@
   R_SExpr reduceLiteral(Literal &Orig) {
     return new (Arena) Literal(Orig);
   }
+  template<class T>
+  R_SExpr reduceLiteralT(LiteralT<T> &Orig) {
+    return new (Arena) LiteralT<T>(Orig);
+  }
   R_SExpr reduceLiteralPtr(LiteralPtr &Orig) {
     return new (Arena) LiteralPtr(Orig);
   }
@@ -170,8 +214,8 @@
   R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) {
     return new (Arena) Store(Orig, E0, E1);
   }
-  R_SExpr reduceArrayFirst(ArrayFirst &Orig, R_SExpr E0) {
-    return new (Arena) ArrayFirst(Orig, E0);
+  R_SExpr reduceArrayIndex(ArrayIndex &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) ArrayIndex(Orig, E0, E1);
   }
   R_SExpr reduceArrayAdd(ArrayAdd &Orig, R_SExpr E0, R_SExpr E1) {
     return new (Arena) ArrayAdd(Orig, E0, E1);
@@ -187,16 +231,20 @@
   }
 
   R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> &Bbs) {
-    return new (Arena) SCFG(Orig, std::move(Bbs.Elems));
+    return nullptr;  // FIXME: implement CFG rewriting
+  }
+  R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
+                                Container<Variable *> &Is, R_SExpr T) {
+    return nullptr;  // FIXME: implement CFG rewriting
   }
   R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
     return new (Arena) Phi(Orig, std::move(As.Elems));
   }
-  R_SExpr reduceGoto(Goto &Orig, BasicBlock *B, unsigned Index) {
-    return new (Arena) Goto(Orig, B, Index);
+  R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) {
+    return new (Arena) Goto(Orig, B, 0);  // FIXME: set index
   }
   R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
-    return new (Arena) Branch(O, C, B0, B1);
+    return new (Arena) Branch(O, C, B0, B1, 0, 0);  // FIXME: set indices
   }
 
   R_SExpr reduceIdentifier(Identifier &Orig) {
@@ -209,12 +257,6 @@
     return new (Arena) Let(Orig, Nvd, B);
   }
 
-  BasicBlock *reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
-                               Container<Variable *> &Is, R_SExpr T) {
-    return new (Arena) BasicBlock(Orig, std::move(As.Elems),
-                                        std::move(Is.Elems), T);
-  }
-
   // Create a new variable from orig, and push it onto the lexical scope.
   Variable *enterScope(Variable &Orig, R_SExpr E0) {
     return new (Arena) Variable(Orig, E0);
@@ -224,49 +266,57 @@
 
   void enterCFG(SCFG &Cfg) {}
   void exitCFG(SCFG &Cfg) {}
+  void enterBasicBlock(BasicBlock &BB) {}
+  void exitBasicBlock(BasicBlock &BB) {}
 
   // Map Variable references to their rewritten definitions.
   Variable *reduceVariableRef(Variable *Ovd) { return Ovd; }
 
-  // Map BasicBlock references to their rewritten defs.
+  // Map BasicBlock references to their rewritten definitions.
   BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
-
-private:
-  MemRegionRef Arena;
 };
 
 
-class SExprCopier : public Traversal<SExprCopier, CopyReducer> {
+class SExprCopier : public CopyReducer<SExprCopier> {
 public:
-  SExprCopier(MemRegionRef A) { setArena(A); }
+  typedef SExpr *R_SExpr;
+
+  SExprCopier(MemRegionRef A) : CopyReducer(A) { }
 
   // Create a copy of e in region a.
   static SExpr *copy(SExpr *E, MemRegionRef A) {
     SExprCopier Copier(A);
-    return Copier.traverse(E);
+    return Copier.traverse(E, TRV_Normal);
   }
 };
 
 
-// Implements a Reducer that visits each subexpression, and returns either
-// true or false.
-class VisitReducer {
-public:
-  VisitReducer() {}
 
+// Base class for visit traversals.
+class VisitReducerBase : public SimpleReducerBase {
+public:
   // A visitor returns a bool, representing success or failure.
   typedef bool R_SExpr;
+  typedef bool R_BasicBlock;
 
   // A visitor "container" is a single bool, which accumulates success.
   template <class T> class Container {
   public:
-    Container(VisitReducer &R, unsigned N) : Success(true) {}
+    Container(VisitReducerBase &S, unsigned N) : Success(true) {}
     void push_back(bool E) { Success = Success && E; }
 
-  private:
-    friend class VisitReducer;
     bool Success;
   };
+};
+
+
+// Implements a traversal that visits each subexpression, and returns either
+// true or false.
+template <class Self>
+class VisitReducer : public Traversal<Self, VisitReducerBase>,
+                     public VisitReducerBase {
+public:
+  VisitReducer() {}
 
 public:
   R_SExpr reduceNull() { return true; }
@@ -274,6 +324,8 @@
   R_SExpr reduceWildcard(Wildcard &Orig) { return true; }
 
   R_SExpr reduceLiteral(Literal &Orig) { return true; }
+  template<class T>
+  R_SExpr reduceLiteralT(LiteralT<T> &Orig) { return true; }
   R_SExpr reduceLiteralPtr(Literal &Orig) { return true; }
 
   R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
@@ -299,7 +351,9 @@
   R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) { return E0; }
   R_SExpr reduceLoad(Load &Orig, R_SExpr E0) { return E0; }
   R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; }
-  R_SExpr reduceArrayFirst(Store &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceArrayIndex(Store &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
   R_SExpr reduceArrayAdd(Store &Orig, R_SExpr E0, R_SExpr E1) {
     return E0 && E1;
   }
@@ -312,10 +366,14 @@
   R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> Bbs) {
     return Bbs.Success;
   }
-   R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
+  R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
+                                Container<Variable *> &Is, R_SExpr T) {
+    return (As.Success && Is.Success && T);
+  }
+  R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
     return As.Success;
   }
-  R_SExpr reduceGoto(Goto &Orig, BasicBlock *B, unsigned Index) {
+  R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) {
     return true;
   }
   R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
@@ -332,39 +390,25 @@
     return Nvd && B;
   }
 
-  BasicBlock *reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
-                               Container<Variable *> &Is, R_SExpr T) {
-    return (As.Success && Is.Success && T) ? &Orig : nullptr;
-  }
-
-  Variable *enterScope(Variable &Orig, R_SExpr E0) {
-    return E0 ? &Orig : nullptr;
-  }
+  Variable *enterScope(Variable &Orig, R_SExpr E0) { return &Orig; }
   void exitScope(const Variable &Orig) {}
-
   void enterCFG(SCFG &Cfg) {}
   void exitCFG(SCFG &Cfg) {}
+  void enterBasicBlock(BasicBlock &BB) {}
+  void exitBasicBlock(BasicBlock &BB) {}
 
-  Variable *reduceVariableRef(Variable *Ovd) { return Ovd; }
-
+  Variable   *reduceVariableRef  (Variable *Ovd)   { return Ovd; }
   BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
-};
 
-
-// A visitor will visit each node, and halt if any reducer returns false.
-template <class Self>
-class SExprVisitor : public Traversal<Self, VisitReducer> {
 public:
-  SExprVisitor() : Success(true) {}
-
   bool traverse(SExpr *E, TraversalKind K = TRV_Normal) {
     Success = Success && this->traverseByCase(E);
     return Success;
   }
 
   static bool visit(SExpr *E) {
-    SExprVisitor Visitor;
-    return Visitor.traverse(E);
+    Self Visitor;
+    return Visitor.traverse(E, TRV_Normal);
   }
 
 private:
@@ -431,9 +475,10 @@
 class PrettyPrinter {
 private:
   bool Verbose;  // Print out additional information
+  bool Cleanup;  // Omit redundant decls.
 
 public:
-  PrettyPrinter(bool V = false) : Verbose(V) { }
+  PrettyPrinter(bool V = false, bool C = true) : Verbose(V), Cleanup(C) { }
 
   static void print(SExpr *E, StreamType &SS) {
     Self printer;
@@ -447,15 +492,6 @@
     SS << "\n";
   }
 
-  void printBlockLabel(StreamType & SS, BasicBlock *BB, unsigned index) {
-    if (!BB) {
-      SS << "BB_null";
-      return;
-    }
-    SS << "BB_";
-    SS << BB->blockID();
-  }
-
   // TODO: further distinguish between binary operations.
   static const unsigned Prec_Atom = 0;
   static const unsigned Prec_Postfix = 1;
@@ -488,7 +524,7 @@
       case COP_Alloc:      return Prec_Other;
       case COP_Load:       return Prec_Postfix;
       case COP_Store:      return Prec_Other;
-      case COP_ArrayFirst: return Prec_Postfix;
+      case COP_ArrayIndex: return Prec_Postfix;
       case COP_ArrayAdd:   return Prec_Postfix;
 
       case COP_UnaryOp:    return Prec_Unary;
@@ -496,6 +532,7 @@
       case COP_Cast:       return Prec_Unary;
 
       case COP_SCFG:       return Prec_Decl;
+      case COP_BasicBlock: return Prec_MAX;
       case COP_Phi:        return Prec_Atom;
       case COP_Goto:       return Prec_Atom;
       case COP_Branch:     return Prec_Atom;
@@ -507,6 +544,17 @@
     return Prec_MAX;
   }
 
+  void printBlockLabel(StreamType & SS, BasicBlock *BB, unsigned index) {
+    if (!BB) {
+      SS << "BB_null";
+      return;
+    }
+    SS << "BB_";
+    SS << BB->blockID();
+    SS << ":";
+    SS << index;
+  }
+
   void printSExpr(SExpr *E, StreamType &SS, unsigned P) {
     if (!E) {
       self()->printNull(SS);
@@ -551,9 +599,15 @@
     SS << E->value();
   }
 
+  void printLiteralT(LiteralT<uint8_t> *E, StreamType &SS) {
+    SS << "'" << E->value() << "'";
+  }
+
   void printLiteral(Literal *E, StreamType &SS) {
-    if (E->clangExpr())
+    if (E->clangExpr()) {
       SS << getSourceLiteralString(E->clangExpr());
+      return;
+    }
     else {
       ValueType VT = E->valueType();
       switch (VT.Base) {
@@ -562,7 +616,7 @@
         return;
       }
       case ValueType::BT_Bool: {
-        if (reinterpret_cast<LiteralT<bool>*>(E)->value())
+        if (E->as<bool>().value())
           SS << "true";
         else
           SS << "false";
@@ -572,27 +626,27 @@
         switch (VT.Size) {
         case ValueType::ST_8:
           if (VT.Signed)
-            printLiteralT(reinterpret_cast<LiteralT<int8_t>*>(E), SS);
+            printLiteralT(&E->as<int8_t>(), SS);
           else
-            printLiteralT(reinterpret_cast<LiteralT<uint8_t>*>(E), SS);
+            printLiteralT(&E->as<uint8_t>(), SS);
           return;
         case ValueType::ST_16:
           if (VT.Signed)
-            printLiteralT(reinterpret_cast<LiteralT<int16_t>*>(E), SS);
+            printLiteralT(&E->as<int16_t>(), SS);
           else
-            printLiteralT(reinterpret_cast<LiteralT<uint16_t>*>(E), SS);
+            printLiteralT(&E->as<uint16_t>(), SS);
           return;
         case ValueType::ST_32:
           if (VT.Signed)
-            printLiteralT(reinterpret_cast<LiteralT<int32_t>*>(E), SS);
+            printLiteralT(&E->as<int32_t>(), SS);
           else
-            printLiteralT(reinterpret_cast<LiteralT<uint32_t>*>(E), SS);
+            printLiteralT(&E->as<uint32_t>(), SS);
           return;
         case ValueType::ST_64:
           if (VT.Signed)
-            printLiteralT(reinterpret_cast<LiteralT<int64_t>*>(E), SS);
+            printLiteralT(&E->as<int64_t>(), SS);
           else
-            printLiteralT(reinterpret_cast<LiteralT<uint64_t>*>(E), SS);
+            printLiteralT(&E->as<uint64_t>(), SS);
           return;
         default:
           break;
@@ -602,10 +656,10 @@
       case ValueType::BT_Float: {
         switch (VT.Size) {
         case ValueType::ST_32:
-          printLiteralT(reinterpret_cast<LiteralT<float>*>(E), SS);
+          printLiteralT(&E->as<float>(), SS);
           return;
         case ValueType::ST_64:
-          printLiteralT(reinterpret_cast<LiteralT<double>*>(E), SS);
+          printLiteralT(&E->as<double>(), SS);
           return;
         default:
           break;
@@ -614,7 +668,7 @@
       }
       case ValueType::BT_String: {
         SS << "\"";
-        printLiteralT(reinterpret_cast<LiteralT<bool>*>(E), SS);
+        printLiteralT(&E->as<StringRef>(), SS);
         SS << "\"";
         return;
       }
@@ -636,20 +690,17 @@
   }
 
   void printVariable(Variable *V, StreamType &SS, bool IsVarDecl = false) {
-    SExpr* E = nullptr;
-    if (!IsVarDecl) {
-      E = getCanonicalVal(V);
+    if (!IsVarDecl && Cleanup) {
+      SExpr* E = getCanonicalVal(V);
       if (E != V) {
         printSExpr(E, SS, Prec_Atom);
-        if (Verbose) {
-          SS << " /*";
-          SS << V->name() << V->getBlockID() << "_" << V->getID();
-          SS << "*/";
-        }
         return;
       }
     }
-    SS << V->name() << V->getBlockID() << "_" << V->getID();
+    if (V->kind() == Variable::VK_LetBB)
+      SS << V->name() << V->getBlockID() << "_" << V->getID();
+    else
+      SS << V->name() << V->getID();
   }
 
   void printFunction(Function *E, StreamType &SS, unsigned sugared = 0) {
@@ -755,15 +806,11 @@
     self()->printSExpr(E->source(), SS, Prec_Other-1);
   }
 
-  void printArrayFirst(ArrayFirst *E, StreamType &SS) {
+  void printArrayIndex(ArrayIndex *E, StreamType &SS) {
     self()->printSExpr(E->array(), SS, Prec_Postfix);
-    if (ArrayAdd *A = dyn_cast_or_null<ArrayAdd>(E->array())) {
-      SS << "[";
-      printSExpr(A->index(), SS, Prec_MAX);
-      SS << "]";
-      return;
-    }
-    SS << "[0]";
+    SS << "[";
+    self()->printSExpr(E->index(), SS, Prec_MAX);
+    SS << "]";
   }
 
   void printArrayAdd(ArrayAdd *E, StreamType &SS) {
@@ -789,40 +836,46 @@
   }
 
   void printSCFG(SCFG *E, StreamType &SS) {
-    SS << "#CFG {\n";
+    SS << "CFG {\n";
     for (auto BBI : *E) {
-      SS << "BB_" << BBI->blockID() << ":";
-      newline(SS);
-      for (auto A : BBI->arguments()) {
-        SS << "let ";
-        self()->printVariable(A, SS, true);
-        SS << " = ";
-        self()->printSExpr(A->definition(), SS, Prec_MAX);
-        SS << ";";
-        newline(SS);
-      }
-      for (auto I : BBI->instructions()) {
-        if (I->definition()->opcode() != COP_Store) {
-          SS << "let ";
-          self()->printVariable(I, SS, true);
-          SS << " = ";
-        }
-        self()->printSExpr(I->definition(), SS, Prec_MAX);
-        SS << ";";
-        newline(SS);
-      }
-      SExpr *T = BBI->terminator();
-      if (T) {
-        self()->printSExpr(T, SS, Prec_MAX);
-        SS << ";";
-        newline(SS);
-      }
-      newline(SS);
+      printBasicBlock(BBI, SS);
     }
     SS << "}";
     newline(SS);
   }
 
+  void printBasicBlock(BasicBlock *E, StreamType &SS) {
+    SS << "BB_" << E->blockID() << ":";
+    if (E->parent())
+      SS << " BB_" << E->parent()->blockID();
+    newline(SS);
+    for (auto *A : E->arguments()) {
+      SS << "let ";
+      self()->printVariable(A, SS, true);
+      SS << " = ";
+      self()->printSExpr(A->definition(), SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    for (auto *I : E->instructions()) {
+      if (I->definition()->opcode() != COP_Store) {
+        SS << "let ";
+        self()->printVariable(I, SS, true);
+        SS << " = ";
+      }
+      self()->printSExpr(I->definition(), SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    SExpr *T = E->terminator();
+    if (T) {
+      self()->printSExpr(T, SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    newline(SS);
+  }
+
   void printPhi(Phi *E, StreamType &SS) {
     SS << "phi(";
     if (E->status() == Phi::PH_SingleVal)
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
index 986103d..31200a3 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -109,8 +109,9 @@
     return *this;
   }
 
+  // Reserve space for at least Ncp items, reallocating if necessary.
   void reserve(size_t Ncp, MemRegionRef A) {
-    if (Ncp < Capacity)
+    if (Ncp <= Capacity)
       return;
     T *Odata = Data;
     Data = A.allocateT<T>(Ncp);
@@ -119,6 +120,14 @@
     return;
   }
 
+  // Reserve space for at least N more items.
+  void reserveCheck(size_t N, MemRegionRef A) {
+    if (Capacity == 0)
+      reserve(u_max(InitialCapacity, N), A);
+    else if (Size + N < Capacity)
+      reserve(u_max(Size + N, Capacity * 2), A);
+  }
+
   typedef T *iterator;
   typedef const T *const_iterator;
 
@@ -163,6 +172,12 @@
   }
 
 private:
+  // std::max is annoying here, because it requires a reference,
+  // thus forcing InitialCapacity to be initialized outside the .h file.
+  size_t u_max(size_t i, size_t j) { return (i < j) ? j : i; }
+
+  static const size_t InitialCapacity = 4;
+
   SimpleArray(const SimpleArray<T> &A) LLVM_DELETED_FUNCTION;
 
   T *Data;
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 7909fdc..891fb90 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -641,6 +641,8 @@
 
   CFG *getParent() const { return Parent; }
 
+  void dump() const;
+
   void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const;
   void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
              bool ShowColors) const;
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 047c307..eebcf46 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -190,6 +190,9 @@
   string Namespace = namespace;
 }
 class Keyword<string name> : Spelling<name, "Keyword">;
+class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
+  string Namespace = namespace;
+}
 
 // The GCC spelling implies GNU<name, "GNU"> and CXX11<"gnu", name> and also
 // sets KnownToGCC to 1. This spelling should be used for any GCC-compatible
@@ -1093,10 +1096,10 @@
 def Section : InheritableAttr {
   let Spellings = [GCC<"section">, Declspec<"allocate">];
   let Args = [StringArgument<"Name">];
-  let Subjects = SubjectList<[Function, GlobalVar, 
+  let Subjects = SubjectList<[Function, GlobalVar,
                               ObjCMethod, ObjCProperty], ErrorDiag,
                              "ExpectedFunctionGlobalVarMethodOrProperty">;
-  let Documentation = [Undocumented];
+  let Documentation = [SectionDocs];
 }
 
 def Sentinel : InheritableAttr {
@@ -1664,13 +1667,13 @@
 
 def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
   let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
-  let Subjects = SubjectList<[Function, Var]>;
+  let Subjects = SubjectList<[Function, Var, CXXRecord]>;
   let Documentation = [Undocumented];
 }
 
 def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
   let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
-  let Subjects = SubjectList<[Function, Var]>;
+  let Subjects = SubjectList<[Function, Var, CXXRecord]>;
   let Documentation = [Undocumented];
 }
 
@@ -1719,7 +1722,6 @@
                    Keyword<"__multiple_inheritance">,
                    Keyword<"__virtual_inheritance">,
                    Keyword<"__unspecified_inheritance">];
-  let Documentation = [SectionDocs];
   let AdditionalMembers = [{
   static bool hasVBPtrOffsetField(Spelling Inheritance) {
     return Inheritance == Keyword_unspecified_inheritance;
@@ -1766,3 +1768,54 @@
 def Unaligned : IgnoredAttr {
   let Spellings = [Keyword<"__unaligned">];
 }
+
+def LoopHint : Attr {
+  /// vectorize: vectorizes loop operations if 'value != 0'.
+  /// vectorize_width: vectorize loop operations with width 'value'.
+  /// interleave: interleave multiple loop iterations if 'value != 0'.
+  /// interleave_count: interleaves 'value' loop interations.
+  /// unroll: unroll loop if 'value != 0'.
+  /// unroll_count: unrolls loop 'value' times.
+
+  let Spellings = [Pragma<"clang", "loop">];
+
+  /// State of the loop optimization specified by the spelling.
+  let Args = [EnumArgument<"Option", "OptionType",
+                          ["vectorize", "vectorize_width", "interleave", "interleave_count",
+                           "unroll", "unroll_count"],
+                          ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
+                           "Unroll", "UnrollCount"]>,
+              DefaultIntArgument<"Value", 1>];
+
+  let AdditionalMembers = [{
+  static StringRef getOptionName(int Option) {
+    switch(Option) {
+    case Vectorize: return "vectorize";
+    case VectorizeWidth: return "vectorize_width";
+    case Interleave: return "interleave";
+    case InterleaveCount: return "interleave_count";
+    case Unroll: return "unroll";
+    case UnrollCount: return "unroll_count";
+    }
+    llvm_unreachable("Unhandled LoopHint option.");
+  }
+
+  static StringRef getValueName(int Value) {
+    if (Value)
+      return "enable";
+    return "disable";
+  }
+
+  void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
+    OS << getOptionName(option) << "(";
+    if (option == VectorizeWidth || option == InterleaveCount ||
+        option == UnrollCount)
+      OS << value;
+    else
+      OS << getValueName(value);
+    OS << ")\n";
+  }
+  }];
+
+  let Documentation = [LoopHintDocs];
+}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 6195960..947c9ba 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -33,6 +33,7 @@
 The ``section`` attribute allows you to specify a specific section a
 global variable or function should be in after translation.
   }];
+  let Heading = "section (gnu::section, __declspec(allocate))";
 }
 
 def TLSModelDocs : Documentation {
@@ -166,7 +167,7 @@
 
 The enable_if expression is evaluated as if it were the body of a
 bool-returning constexpr function declared with the arguments of the function
-it is being applied to, then called with the parameters at the callsite. If the
+it is being applied to, then called with the parameters at the call site. If the
 result is false or could not be determined through constant expression
 evaluation, then this overload will not be chosen and the provided string may
 be used in a diagnostic if the compile fails as a result.
@@ -633,7 +634,7 @@
   let Category = DocCatConsumed;
   let Content = [{
 Annotate methods that transition an object into a new state with
-``__attribute__((set_typestate(new_state)))``.  The new new state must be
+``__attribute__((set_typestate(new_state)))``.  The new state must be
 unconsumed, consumed, or unknown.
   }];
 }
@@ -911,7 +912,7 @@
    Clang implements this mostly the same way as GCC, but there is a difference
    for functions that accept a ``va_list`` argument (for example, ``vprintf``).
    GCC does not emit ``-Wformat-nonliteral`` warning for calls to such
-   fuctions.  Clang does not warn if the format string comes from a function
+   functions.  Clang does not warn if the format string comes from a function
    parameter, where the function is annotated with a compatible attribute,
    otherwise it warns.  For example:
 
@@ -1011,3 +1012,15 @@
   }];
 }
 
+def LoopHintDocs : Documentation {
+  let Category = DocCatStmt;
+  let Content = [{
+The ``#pragma clang loop`` directive allows loop optimization hints to be
+specified for the subsequent loop. The directive allows vectorization,
+interleaving, and unrolling to be enabled or disabled. Vector width as well
+as interleave and unrolling count can be manually specified. See
+`language extensions
+<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
+for details.
+  }];
+}
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
index 4a7e462..5783b3b 100644
--- a/include/clang/Basic/Attributes.h
+++ b/include/clang/Basic/Attributes.h
@@ -25,7 +25,9 @@
   /// Is the identifier known as a __declspec-style attribute?
   Declspec,
   // Is the identifier known as a C++-style attribute?
-  CXX
+  CXX,
+  // Is the identifier known as a pragma attribute?
+  Pragma
 };
 
 /// \brief Return true if we recognize and implement the attribute specified by
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 3a1c58f..a7a7f42 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -73,7 +73,7 @@
 //       be followed by ':headername:' to state which header this function
 //       comes from.
 //  i -> this is a runtime library implemented function without the
-//       '__builtin_' prefix. It will be implemented in compiter-rt or libgcc.
+//       '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
 //  p:N: -> this is a printf-like function whose Nth argument is the format
 //          string.
 //  P:N: -> similar to the p:N: attribute, but the function is like vprintf
@@ -683,9 +683,12 @@
 LANGBUILTIN(__debugbreak, "v",   "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__va_start,   "vc**.", "nt", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
 
 // C99 library functions
 // C99 stdlib.h
@@ -1204,6 +1207,8 @@
 
 // Clang builtins (not available in GCC).
 BUILTIN(__builtin_addressof, "v*v&", "nct")
+BUILTIN(__builtin_operator_new, "v*z", "c")
+BUILTIN(__builtin_operator_delete, "vv*", "n")
 
 #undef BUILTIN
 #undef LIBBUILTIN
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index 36dcb9f..c3852fb 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -18,9 +18,15 @@
 BUILTIN(__clear_cache, "vv*v*", "i")
 
 BUILTIN(__builtin_arm_ldrex, "v.", "t")
+BUILTIN(__builtin_arm_ldaex, "v.", "t")
 BUILTIN(__builtin_arm_strex, "i.", "t")
+BUILTIN(__builtin_arm_stlex, "i.", "t")
 BUILTIN(__builtin_arm_clrex, "v", "")
 
+// Bit manipulation
+BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
+BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc")
+
 // CRC32
 BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
 BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 9f650cc..d1cf9a7 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -14,6 +14,10 @@
 
 // The format of this database matches clang/Basic/Builtins.def.
 
+#if defined(BUILTIN) && !defined(LANGBUILTIN)
+#   define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
 // In libgcc
 BUILTIN(__clear_cache, "vv*v*", "i")
 BUILTIN(__builtin_thread_pointer, "v*", "")
@@ -24,12 +28,17 @@
 BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
 BUILTIN(__builtin_arm_usat, "UiUiUi", "nc")
 
+// Bit manipulation
+BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
+
 // Store and load exclusive
 BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "")
 BUILTIN(__builtin_arm_strexd, "iLLUiv*", "")
 
 BUILTIN(__builtin_arm_ldrex, "v.", "t")
+BUILTIN(__builtin_arm_ldaex, "v.", "t")
 BUILTIN(__builtin_arm_strex, "i.", "t")
+BUILTIN(__builtin_arm_stlex, "i.", "t")
 BUILTIN(__builtin_arm_clrex, "v", "")
 
 // VFP
@@ -59,14 +68,32 @@
 BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
 
 // HINT
-BUILTIN(__yield, "v", "")
-BUILTIN(__wfe, "v", "")
-BUILTIN(__wfi, "v", "")
-BUILTIN(__sev, "v", "")
-BUILTIN(__sevl, "v", "")
+BUILTIN(__builtin_arm_yield, "v", "")
+BUILTIN(__builtin_arm_wfe, "v", "")
+BUILTIN(__builtin_arm_wfi, "v", "")
+BUILTIN(__builtin_arm_sev, "v", "")
+BUILTIN(__builtin_arm_sevl, "v", "")
 
 // Data barrier
 BUILTIN(__builtin_arm_dmb, "vUi", "nc")
 BUILTIN(__builtin_arm_dsb, "vUi", "nc")
+BUILTIN(__builtin_arm_isb, "vUi", "nc")
+
+// MSVC
+LANGBUILTIN(__yield, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfe, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__sev, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
+
+LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__ldrexd, "WiCDWi*", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveFromCoprocessor, "UiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveFromCoprocessor2, "UiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveToCoprocessor, "vUiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveToCoprocessor2, "vUiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
 
 #undef BUILTIN
+#undef LANGBUILTIN
diff --git a/include/clang/Basic/BuiltinsR600.def b/include/clang/Basic/BuiltinsR600.def
new file mode 100644
index 0000000..e0812d7
--- /dev/null
+++ b/include/clang/Basic/BuiltinsR600.def
@@ -0,0 +1,20 @@
+//==- BuiltinsR600.def - R600 Builtin function database ----------*- 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 R600-specific builtin function database. Users of this
+// file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+BUILTIN(__builtin_amdgpu_div_scale, "dddbb*", "n")
+BUILTIN(__builtin_amdgpu_div_scalef, "fffbb*", "n")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 8faaea3..1f377a8 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -453,9 +453,6 @@
 BUILTIN(__builtin_ia32_movmskps256, "iV8f", "")
 BUILTIN(__builtin_ia32_vzeroall, "v", "")
 BUILTIN(__builtin_ia32_vzeroupper, "v", "")
-BUILTIN(__builtin_ia32_vbroadcastss, "V4ffC*", "")
-BUILTIN(__builtin_ia32_vbroadcastsd256, "V4ddC*", "")
-BUILTIN(__builtin_ia32_vbroadcastss256, "V8ffC*", "")
 BUILTIN(__builtin_ia32_vbroadcastf128_pd256, "V4dV2dC*", "")
 BUILTIN(__builtin_ia32_vbroadcastf128_ps256, "V8fV4fC*", "")
 BUILTIN(__builtin_ia32_storeupd256, "vd*V4d", "")
@@ -760,6 +757,7 @@
 BUILTIN(__builtin_ia32_xend, "v", "")
 BUILTIN(__builtin_ia32_xabort, "vIc", "")
 BUILTIN(__builtin_ia32_xtest, "i", "")
+BUILTIN(__builtin_ia32_rdpmc, "ULLii", "")
 BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
 BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
 
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 4926cec..4dc8aeb 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -146,13 +146,6 @@
     Fatal = DiagnosticIDs::Fatal
   };
 
-  /// \brief How do we handle otherwise-unmapped extension?
-  ///
-  /// This is controlled by -pedantic and -pedantic-errors.
-  enum ExtensionHandling {
-    Ext_Ignore, Ext_Warn, Ext_Error
-  };
-
   enum ArgumentKind {
     ak_std_string,      ///< std::string
     ak_c_string,        ///< const char *
@@ -190,7 +183,7 @@
                                    // 0 -> no limit.
   unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
                                     // backtrace stack, 0 -> no limit.
-  ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
+  diag::Severity ExtBehavior;       // Map extensions to warnings or errors?
   IntrusiveRefCntPtr<DiagnosticIDs> Diags;
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
   DiagnosticConsumer *Client;
@@ -200,7 +193,7 @@
   /// \brief Mapping information for diagnostics.
   ///
   /// Mapping info is packed into four bits per diagnostic.  The low three
-  /// bits are the mapping (an instance of diag::Mapping), or zero if unset.
+  /// bits are the mapping (an instance of diag::Severity), or zero if unset.
   /// The high bit is set when the mapping was established as a user mapping.
   /// If the high bit is clear, then the low bits are set to the default
   /// value, and should be mapped with -pedantic, -Werror, etc.
@@ -209,19 +202,18 @@
   /// the state so that we know what is the diagnostic state at any given
   /// source location.
   class DiagState {
-    llvm::DenseMap<unsigned, DiagnosticMappingInfo> DiagMap;
+    llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap;
 
   public:
-    typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::iterator
-      iterator;
-    typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::const_iterator
-      const_iterator;
+    typedef llvm::DenseMap<unsigned, DiagnosticMapping>::iterator iterator;
+    typedef llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator
+    const_iterator;
 
-    void setMappingInfo(diag::kind Diag, DiagnosticMappingInfo Info) {
+    void setMapping(diag::kind Diag, DiagnosticMapping Info) {
       DiagMap[Diag] = Info;
     }
 
-    DiagnosticMappingInfo &getOrAddMappingInfo(diag::kind Diag);
+    DiagnosticMapping &getOrAddMapping(diag::kind Diag);
 
     const_iterator begin() const { return DiagMap.begin(); }
     const_iterator end() const { return DiagMap.end(); }
@@ -317,17 +309,15 @@
   ///
   /// This takes the modifiers and argument that was present in the diagnostic.
   ///
-  /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
-  /// arguments formatted for this diagnostic.  Implementations of this function
-  /// can use this information to avoid redundancy across arguments.
+  /// The PrevArgs array indicates the previous arguments formatted for this
+  /// diagnostic.  Implementations of this function can use this information to
+  /// avoid redundancy across arguments.
   ///
   /// This is a hack to avoid a layering violation between libbasic and libsema.
   typedef void (*ArgToStringFnTy)(
       ArgumentKind Kind, intptr_t Val,
-      const char *Modifier, unsigned ModifierLen,
-      const char *Argument, unsigned ArgumentLen,
-      const ArgumentValue *PrevArgs,
-      unsigned NumPrevArgs,
+      StringRef Modifier, StringRef Argument,
+      ArrayRef<ArgumentValue> PrevArgs,
       SmallVectorImpl<char> &Output,
       void *Cookie,
       ArrayRef<intptr_t> QualTypeVals);
@@ -345,13 +335,12 @@
   /// \brief Second string argument for the delayed diagnostic.
   std::string DelayedDiagArg2;
 
-  /// \brief Flag name value.
+  /// \brief Optional flag value.
   ///
-  /// Some flags accept values. For instance, -Wframe-larger-than or -Rpass.
-  /// When reporting a diagnostic with those flags, it is useful to also
-  /// report the value that actually triggered the flag. The content of this
-  /// string is a value to be emitted after the flag name.
-  std::string FlagNameValue;
+  /// Some flags accept values, for instance: -Wframe-larger-than=<value> and
+  /// -Rpass=<value>. The content of this string is emitted after the flag name
+  /// and '='.
+  std::string FlagValue;
 
 public:
   explicit DiagnosticsEngine(
@@ -526,10 +515,8 @@
   /// mapped onto ignore/warning/error. 
   ///
   /// This corresponds to the GCC -pedantic and -pedantic-errors option.
-  void setExtensionHandlingBehavior(ExtensionHandling H) {
-    ExtBehavior = H;
-  }
-  ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; }
+  void setExtensionHandlingBehavior(diag::Severity H) { ExtBehavior = H; }
+  diag::Severity getExtensionHandlingBehavior() const { return ExtBehavior; }
 
   /// \brief Counter bumped when an __extension__  block is/ encountered.
   ///
@@ -547,8 +534,7 @@
   ///
   /// \param Loc The source location that this change of diagnostic state should
   /// take affect. It can be null if we are setting the latest state.
-  void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
-                            SourceLocation Loc);
+  void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc);
 
   /// \brief Change an entire diagnostic group (e.g. "unknown-pragmas") to
   /// have the specified mapping.
@@ -558,8 +544,8 @@
   ///
   /// \param Loc The source location that this change of diagnostic state should
   /// take affect. It can be null if we are setting the state from command-line.
-  bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map,
-                                 SourceLocation Loc = SourceLocation());
+  bool setSeverityForGroup(StringRef Group, diag::Severity Map,
+                           SourceLocation Loc = SourceLocation());
 
   /// \brief Set the warning-as-error flag for the given diagnostic group.
   ///
@@ -579,8 +565,8 @@
   ///
   /// Mainly to be used by -Wno-everything to disable all warnings but allow
   /// subsequent -W options to enable specific warnings.
-  void setMappingToAllDiagnostics(diag::Mapping Map,
-                                  SourceLocation Loc = SourceLocation());
+  void setSeverityForAll(diag::Severity Map,
+                         SourceLocation Loc = SourceLocation());
 
   bool hasErrorOccurred() const { return ErrorOccurred; }
 
@@ -619,14 +605,12 @@
   /// \brief Converts a diagnostic argument (as an intptr_t) into the string
   /// that represents it.
   void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
-                          const char *Modifier, unsigned ModLen,
-                          const char *Argument, unsigned ArgLen,
-                          const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
+                          StringRef Modifier, StringRef Argument,
+                          ArrayRef<ArgumentValue> PrevArgs,
                           SmallVectorImpl<char> &Output,
                           ArrayRef<intptr_t> QualTypeVals) const {
-    ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
-                  PrevArgs, NumPrevArgs, Output, ArgToStringCookie,
-                  QualTypeVals);
+    ArgToStringFn(Kind, Val, Modifier, Argument, PrevArgs, Output,
+                  ArgToStringCookie, QualTypeVals);
   }
 
   void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
@@ -648,10 +632,27 @@
   // DiagnosticsEngine classification and reporting interfaces.
   //
 
+  /// \brief Determine whether the diagnostic is known to be ignored.
+  ///
+  /// This can be used to opportunistically avoid expensive checks when it's
+  /// known for certain that the diagnostic has been suppressed at the
+  /// specified location \p Loc.
+  ///
+  /// \param Loc The source location we are interested in finding out the
+  /// diagnostic state. Can be null in order to query the latest state.
+  bool isIgnored(unsigned DiagID, SourceLocation Loc) const {
+    return Diags->getDiagnosticSeverity(DiagID, Loc, *this) ==
+           diag::Severity::Ignored;
+  }
+
   /// \brief Based on the way the client configured the DiagnosticsEngine
   /// object, classify the specified diagnostic ID into a Level, consumable by
   /// the DiagnosticConsumer.
   ///
+  /// To preserve invariant assumptions, this function should not be used to
+  /// influence parse or semantic analysis actions. Instead consider using
+  /// \c isIgnored().
+  ///
   /// \param Loc The source location we are interested in finding out the
   /// diagnostic state. Can be null in order to query the latest state.
   Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
@@ -701,11 +702,8 @@
   /// \brief Clear out the current diagnostic.
   void Clear() { CurDiagID = ~0U; }
 
-  /// \brief Return the value associated to this diagnostic flag.
-  StringRef getFlagNameValue() const { return StringRef(FlagNameValue); }
-
-  /// \brief Set the value associated to this diagnostic flag.
-  void setFlagNameValue(StringRef V) { FlagNameValue = V; }
+  /// \brief Return the value associated with this diagnostic flag.
+  StringRef getFlagValue() const { return FlagValue; }
 
 private:
   /// \brief Report the delayed diagnostic.
@@ -770,19 +768,19 @@
   /// or modify at a particular position.
   SmallVector<FixItHint, 8> DiagFixItHints;
 
-  DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) {
+  DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
     bool isPragma = L.isValid();
-    DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make(
-      Map, /*IsUser=*/true, isPragma);
+    DiagnosticMapping Mapping =
+        DiagnosticMapping::Make(Map, /*IsUser=*/true, isPragma);
 
     // If this is a pragma mapping, then set the diagnostic mapping flags so
     // that we override command line options.
     if (isPragma) {
-      MappingInfo.setNoWarningAsError(true);
-      MappingInfo.setNoErrorAsFatal(true);
+      Mapping.setNoWarningAsError(true);
+      Mapping.setNoErrorAsFatal(true);
     }
 
-    return MappingInfo;
+    return Mapping;
   }
 
   /// \brief Used to report a diagnostic that is finally fully formed.
@@ -995,7 +993,7 @@
     DiagObj->DiagFixItHints.push_back(Hint);
   }
 
-  void addFlagValue(StringRef V) const { DiagObj->setFlagNameValue(V); }
+  void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; }
 };
 
 struct AddFlagValue {
@@ -1106,7 +1104,7 @@
   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
   CurDiagLoc = Loc;
   CurDiagID = DiagID;
-  FlagNameValue.clear();
+  FlagValue.clear();
   return DiagnosticBuilder(this);
 }
 
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index 5bcc2d5..48cbf09 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -12,13 +12,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Define the diagnostic mappings.
-class DiagMapping;
-def MAP_IGNORE  : DiagMapping;
-def MAP_REMARK  : DiagMapping;
-def MAP_WARNING : DiagMapping;
-def MAP_ERROR   : DiagMapping;
-def MAP_FATAL   : DiagMapping;
+// Define the diagnostic severities.
+class Severity<string N> {
+  string Name = N;
+}
+def SEV_Ignored : Severity<"Ignored">;
+def SEV_Remark  : Severity<"Remark">;
+def SEV_Warning : Severity<"Warning">;
+def SEV_Error   : Severity<"Error">;
+def SEV_Fatal   : Severity<"Fatal">;
 
 // Define the diagnostic classes.
 class DiagClass;
@@ -59,7 +61,7 @@
 
 
 // All diagnostics emitted by the compiler are an indirect subclass of this.
-class Diagnostic<string text, DiagClass DC, DiagMapping defaultmapping> {
+class Diagnostic<string text, DiagClass DC, Severity defaultmapping> {
   /// Component is specified by the file with a big let directive.
   string         Component = ?;
   string         Text = text;
@@ -67,8 +69,8 @@
   SFINAEResponse SFINAE = SFINAE_Suppress;
   bit            AccessControl = 0;
   bit            WarningNoWerror = 0;
-  bit            WarningShowInSystemHeader = 0;
-  DiagMapping    DefaultMapping = defaultmapping;
+  bit            ShowInSystemHeader = 0;
+  Severity       DefaultSeverity = defaultmapping;
   DiagGroup      Group;
   string         CategoryName = "";
 }
@@ -83,26 +85,33 @@
   SFINAEResponse SFINAE = SFINAE_AccessControl;
 }
 
+class ShowInSystemHeader {
+  bit ShowInSystemHeader = 1;
+}
+
+class SuppressInSystemHeader {
+  bit ShowInSystemHeader = 0;
+}
+
 // FIXME: ExtWarn and Extension should also be SFINAEFailure by default.
-class Error<string str>     : Diagnostic<str, CLASS_ERROR, MAP_ERROR>, SFINAEFailure;
-class Warning<string str>   : Diagnostic<str, CLASS_WARNING, MAP_WARNING>;
-class Remark<string str>    : Diagnostic<str, CLASS_REMARK, MAP_IGNORE>;
-class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_IGNORE>;
-class ExtWarn<string str>   : Diagnostic<str, CLASS_EXTENSION, MAP_WARNING>;
-class Note<string str>      : Diagnostic<str, CLASS_NOTE, MAP_FATAL/*ignored*/>;
+class Error<string str>     : Diagnostic<str, CLASS_ERROR, SEV_Error>, SFINAEFailure {
+  bit ShowInSystemHeader = 1;
+}
+class Warning<string str>   : Diagnostic<str, CLASS_WARNING, SEV_Warning>;
+class Remark<string str>    : Diagnostic<str, CLASS_REMARK, SEV_Ignored>;
+class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, SEV_Ignored>;
+class ExtWarn<string str>   : Diagnostic<str, CLASS_EXTENSION, SEV_Warning>;
+class Note<string str>      : Diagnostic<str, CLASS_NOTE, SEV_Fatal/*ignored*/>;
 
 
-class DefaultIgnore { DiagMapping DefaultMapping = MAP_IGNORE; }
-class DefaultWarn   { DiagMapping DefaultMapping = MAP_WARNING; }
-class DefaultError  { DiagMapping DefaultMapping = MAP_ERROR; }
-class DefaultFatal  { DiagMapping DefaultMapping = MAP_FATAL; }
+class DefaultIgnore { Severity DefaultSeverity = SEV_Ignored; }
+class DefaultWarn   { Severity DefaultSeverity = SEV_Warning; }
+class DefaultError  { Severity DefaultSeverity = SEV_Error; }
+class DefaultFatal  { Severity DefaultSeverity = SEV_Fatal; }
 class DefaultWarnNoWerror {
   bit WarningNoWerror = 1;
 }
-class DefaultWarnShowInSystemHeader {
-  bit WarningShowInSystemHeader = 1;
-}
-class DefaultRemark { DiagMapping DefaultMapping = MAP_REMARK; }
+class DefaultRemark { Severity DefaultSeverity = SEV_Remark; }
 
 // Definitions for Diagnostics.
 include "DiagnosticASTKinds.td"
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 113e564..8d5a1c7 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -89,6 +89,9 @@
   "constexpr evaluation hit maximum call limit">;
 def note_constexpr_step_limit_exceeded : Note<
   "constexpr evaluation hit maximum step limit; possible infinite loop?">;
+def note_constexpr_this : Note<
+  "%select{|implicit }0use of 'this' pointer is only allowed within the "
+  "evaluation of a call to a 'constexpr' member function">;
 def note_constexpr_lifetime_ended : Note<
   "%select{read of|assignment to|increment of|decrement of}0 "
   "%select{temporary|variable}1 whose lifetime has ended">;
@@ -138,6 +141,7 @@
   "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to "
   "see all)">;
 def note_constexpr_call_here : Note<"in call to '%0'">;
+
 def warn_integer_constant_overflow : Warning<
   "overflow in expression; result is %0 with type %1">,
   InGroup<DiagGroup<"integer-overflow">>;
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 74d628e..b3c77b8 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -138,7 +138,7 @@
 
 // TransformActions
 // TODO: Use a custom category name to distinguish rewriter errors.
-def err_mt_message : Error<"[rewriter] %0">;
+def err_mt_message : Error<"[rewriter] %0">, SuppressInSystemHeader;
 def warn_mt_message : Warning<"[rewriter] %0">;
 def note_mt_message : Note<"[rewriter] %0">;
 
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 1da7a16..b5a807e 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -22,6 +22,8 @@
 def err_drv_unknown_language : Error<"language not recognized: '%0'">;
 def err_drv_invalid_arch_name : Error<
   "invalid arch name '%0'">;
+def err_drv_invalid_linker_name : Error<
+  "invalid linker name in argument '%0'">;
 def err_drv_invalid_rtlib_name : Error<
   "invalid runtime library name in argument '%0'">;
 def err_drv_unsupported_rtlib_for_platform : Error<
@@ -137,8 +139,6 @@
 def warn_drv_empty_joined_argument : Warning<
   "joined argument expects additional value: '%0'">,
   InGroup<UnusedCommandLineArgument>;
-def warn_drv_unused_sanitizer : Warning<"'%0' is ignored in absence of '%1'">,
-  InGroup<UnusedSanitizeArgument>;
 def warn_drv_clang_unsupported : Warning<
   "the clang compiler does not support '%0'">;
 def warn_drv_assuming_mfloat_abi_is : Warning<
@@ -176,7 +176,4 @@
 
 def warn_drv_invoking_fallback : Warning<"falling back to %0">,
   InGroup<Fallback>;
-def warn_drv_rtti_fallback :
-  Warning<"cannot compile RTTI yet, falling back to %0">,
-  InGroup<Fallback>;
 }
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 91faa0a..c08ac99 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+class BackendInfo : CatBackend, ShowInSystemHeader;
+
 let Component = "Frontend" in {
 
 def err_fe_error_opening : Error<"error opening '%0': %1">;
@@ -14,7 +16,6 @@
 def err_fe_error_reading_stdin : Error<"error reading stdin: %0">;
 def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
 
-// Error generated by the backend.
 def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
 def warn_fe_inline_asm : Warning<"%0">, CatInlineAsm, InGroup<BackendInlineAsm>;
 def note_fe_inline_asm : Note<"%0">, CatInlineAsm;
@@ -22,21 +23,24 @@
 def err_fe_cannot_link_module : Error<"cannot link module '%0': %1">,
   DefaultFatal;
 
-def warn_fe_backend_frame_larger_than: Warning<"stack size exceeded (%0) in %1">,
-    CatBackend, InGroup<BackendFrameLargerThan>;
-def err_fe_backend_frame_larger_than: Error<"%0">, CatBackend;
-def note_fe_backend_frame_larger_than: Note<"%0">, CatBackend;
+def warn_fe_frame_larger_than : Warning<"stack frame size of %0 bytes in %q1">,
+    BackendInfo, InGroup<BackendFrameLargerThanEQ>;
+def warn_fe_backend_frame_larger_than: Warning<"%0">,
+    BackendInfo, InGroup<BackendFrameLargerThanEQ>;
+def err_fe_backend_frame_larger_than: Error<"%0">, BackendInfo;
+def note_fe_backend_frame_larger_than: Note<"%0">, BackendInfo;
 
-def warn_fe_backend_plugin: Warning<"%0">, CatBackend, InGroup<BackendPlugin>;
-def err_fe_backend_plugin: Error<"%0">, CatBackend;
-def remark_fe_backend_plugin: Remark<"%0">, CatBackend, InGroup<RemarkBackendPlugin>;
-def note_fe_backend_plugin: Note<"%0">, CatBackend;
+def warn_fe_backend_plugin: Warning<"%0">, BackendInfo, InGroup<BackendPlugin>;
+def err_fe_backend_plugin: Error<"%0">, BackendInfo;
+def remark_fe_backend_plugin: Remark<"%0">, BackendInfo, InGroup<RemarkBackendPlugin>;
+def note_fe_backend_plugin: Note<"%0">, BackendInfo;
 
-def remark_fe_backend_optimization_remark : Remark<"%0">, CatBackend,
+def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo,
     InGroup<BackendOptimizationRemark>, DefaultRemark;
-def note_fe_backend_optimization_remark_missing_loc : Note<"use "
-  "-gline-tables-only -gcolumn-info to track source location information "
-  "for this optimization remark">;
+def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo,
+    InGroup<BackendOptimizationRemarkMissed>, DefaultRemark;
+def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo,
+    InGroup<BackendOptimizationRemarkAnalysis>, DefaultRemark;
 def note_fe_backend_optimization_remark_invalid_loc : Note<"could "
   "not determine the original source location for %0:%1:%2">;
 
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 485b48d..3d10fcf 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -38,7 +38,9 @@
 def StringConversion : DiagGroup<"string-conversion">;
 def SignConversion : DiagGroup<"sign-conversion">;
 def PointerBoolConversion : DiagGroup<"pointer-bool-conversion">;
-def BoolConversion : DiagGroup<"bool-conversion", [ PointerBoolConversion ] >;
+def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">;
+def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion,
+                                                   UndefinedBoolConversion]>;
 def IntConversion : DiagGroup<"int-conversion">;
 def EnumConversion : DiagGroup<"enum-conversion">;
 def FloatConversion : DiagGroup<"float-conversion">;
@@ -119,6 +121,9 @@
 def CXXPre1yCompat : DiagGroup<"c++98-c++11-compat">;
 def CXXPre1yCompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic",
                                        [CXXPre1yCompat]>;
+def CXXPre1zCompat : DiagGroup<"c++98-c++11-c++14-compat">;
+def CXXPre1zCompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
+                                       [CXXPre1zCompat]>;
 
 def CXX98CompatBindToTemporaryCopy :
   DiagGroup<"c++98-compat-bind-to-temporary-copy">;
@@ -131,11 +136,13 @@
                             [CXX98CompatBindToTemporaryCopy,
                              CXX98CompatLocalTypeTemplateArgs,
                              CXX98CompatUnnamedTypeTemplateArgs,
-                             CXXPre1yCompat]>;
+                             CXXPre1yCompat,
+                             CXXPre1zCompat]>;
 // Warnings for C++11 features which are Extensions in C++98 mode.
 def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
                                     [CXX98Compat,
-                                     CXXPre1yCompatPedantic]>;
+                                     CXXPre1yCompatPedantic,
+                                     CXXPre1zCompatPedantic]>;
 
 def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
 
@@ -155,10 +162,16 @@
                             [CXX11Narrowing,
                              CXX11CompatReservedUserDefinedLiteral,
                              CXX11CompatDeprecatedWritableStr,
-                             CXXPre1yCompat]>;
+                             CXXPre1yCompat,
+                             CXXPre1zCompat]>;
 def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
 def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
-                                    [CXXPre1yCompatPedantic]>;
+                                    [CXXPre1yCompatPedantic,
+                                     CXXPre1zCompatPedantic]>;
+
+def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre1zCompat]>;
+def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
+                                    [CXXPre1zCompatPedantic]>;
 
 def : DiagGroup<"effc++">;
 def DivZero : DiagGroup<"division-by-zero">;
@@ -242,6 +255,7 @@
 def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
 def PrivateExtern : DiagGroup<"private-extern">;
 def SelTypeCast : DiagGroup<"cast-of-sel-type">;
+def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">;
 def BadFunctionCast : DiagGroup<"bad-function-cast">;
 def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
 def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
@@ -257,8 +271,7 @@
 def Packed : DiagGroup<"packed">;
 def Padded : DiagGroup<"padded">;
 def PointerArith : DiagGroup<"pointer-arith">;
-def PoundWarning : DiagGroup<"#warnings">,
-                   DiagCategory<"#warning Directive">;
+def PoundWarning : DiagGroup<"#warnings">;
 def PoundPragmaMessage : DiagGroup<"#pragma-messages">,
                          DiagCategory<"#pragma message Directive">;
 def : DiagGroup<"pointer-to-int-cast">;
@@ -297,10 +310,12 @@
 def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
 def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
 def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
+def TautologicalUndefinedCompare : DiagGroup<"tautological-undefined-compare">;
 def TautologicalCompare : DiagGroup<"tautological-compare",
                                     [TautologicalOutOfRangeCompare,
                                      TautologicalPointerCompare,
-                                     TautologicalOverlapCompare]>;
+                                     TautologicalOverlapCompare,
+                                     TautologicalUndefinedCompare]>;
 def HeaderHygiene : DiagGroup<"header-hygiene">;
 def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
 def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
@@ -367,9 +382,7 @@
                                         [CXX98CompatUnnamedTypeTemplateArgs]>;
 def UnsupportedFriend : DiagGroup<"unsupported-friend">;
 def UnusedArgument : DiagGroup<"unused-argument">;
-def UnusedSanitizeArgument : DiagGroup<"unused-sanitize-argument">;
-def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument",
-                                          [UnusedSanitizeArgument]>;
+def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument">;
 def InvalidCommandLineArgument : DiagGroup<"invalid-command-line-argument">;
 def UnusedComparison : DiagGroup<"unused-comparison">;
 def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
@@ -615,6 +628,10 @@
 // earlier C++ versions.
 def CXX1y : DiagGroup<"c++1y-extensions">;
 
+// A warning group for warnings about using C++1z features as extensions in
+// earlier C++ versions.
+def CXX1z : DiagGroup<"c++1z-extensions">;
+
 def : DiagGroup<"c++0x-extensions", [CXX11]>;
 def DelegatingCtorCycles :
   DiagGroup<"delegating-ctor-cycles">;
@@ -677,13 +694,17 @@
 // OpenMP warnings.
 def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
 def OpenMPClauses : DiagGroup<"openmp-clauses">;
+def OpenMPLoopForm : DiagGroup<"openmp-loop-form">;
 
 // Backend warnings.
 def BackendInlineAsm : DiagGroup<"inline-asm">;
-def BackendFrameLargerThan : DiagGroup<"frame-larger-than">;
+def BackendFrameLargerThanEQ : DiagGroup<"frame-larger-than=">;
 def BackendPlugin : DiagGroup<"backend-plugin">;
 def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
 def BackendOptimizationRemark : DiagGroup<"pass">;
+def BackendOptimizationRemarkMissed : DiagGroup<"pass-missed">;
+def BackendOptimizationRemarkAnalysis : DiagGroup<"pass-analysis">;
 
 // Instrumentation based profiling warnings.
 def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
+def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index c952e49..8eba2f6 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -56,50 +56,44 @@
     };
 
     /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
-    /// to either MAP_IGNORE (nothing), MAP_REMARK (emit a remark), MAP_WARNING
-    /// (emit a warning), MAP_ERROR (emit as an error).  It allows clients to
-    /// map errors to MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting
-    /// diagnostics after this one).
-    enum Mapping {
+    /// to either Ignore (nothing), Remark (emit a remark), Warning
+    /// (emit a warning) or Error (emit as an error).  It allows clients to
+    /// map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
+    enum class Severity {
       // NOTE: 0 means "uncomputed".
-      MAP_IGNORE  = 1,     ///< Map this diagnostic to nothing, ignore it.
-      MAP_REMARK  = 2,     ///< Map this diagnostic to a remark.
-      MAP_WARNING = 3,     ///< Map this diagnostic to a warning.
-      MAP_ERROR   = 4,     ///< Map this diagnostic to an error.
-      MAP_FATAL   = 5      ///< Map this diagnostic to a fatal error.
+      Ignored = 1, ///< Do not present this diagnostic, ignore it.
+      Remark = 2,  ///< Present this diagnostic as a remark.
+      Warning = 3, ///< Present this diagnostic as a warning.
+      Error = 4,   ///< Present this diagnostic as an error.
+      Fatal = 5    ///< Present this diagnostic as a fatal error.
     };
   }
 
-class DiagnosticMappingInfo {
-  unsigned Mapping : 3;
+class DiagnosticMapping {
+  unsigned Severity : 3;
   unsigned IsUser : 1;
   unsigned IsPragma : 1;
-  unsigned HasShowInSystemHeader : 1;
   unsigned HasNoWarningAsError : 1;
   unsigned HasNoErrorAsFatal : 1;
 
 public:
-  static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser,
-                                    bool IsPragma) {
-    DiagnosticMappingInfo Result;
-    Result.Mapping = Mapping;
+  static DiagnosticMapping Make(diag::Severity Severity, bool IsUser,
+                                bool IsPragma) {
+    DiagnosticMapping Result;
+    Result.Severity = (unsigned)Severity;
     Result.IsUser = IsUser;
     Result.IsPragma = IsPragma;
-    Result.HasShowInSystemHeader = 0;
     Result.HasNoWarningAsError = 0;
     Result.HasNoErrorAsFatal = 0;
     return Result;
   }
 
-  diag::Mapping getMapping() const { return diag::Mapping(Mapping); }
-  void setMapping(diag::Mapping Value) { Mapping = Value; }
+  diag::Severity getSeverity() const { return (diag::Severity)Severity; }
+  void setSeverity(diag::Severity Value) { Severity = (unsigned)Value; }
 
   bool isUser() const { return IsUser; }
   bool isPragma() const { return IsPragma; }
 
-  bool hasShowInSystemHeader() const { return HasShowInSystemHeader; }
-  void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; }
-
   bool hasNoWarningAsError() const { return HasNoWarningAsError; }
   void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
 
@@ -154,9 +148,6 @@
   /// default.
   static bool isDefaultMappingAsError(unsigned DiagID);
 
-  /// \brief Return true if the specified diagnostic is a Remark.
-  static bool isRemark(unsigned DiagID);
-
   /// \brief Determine whether the given built-in diagnostic ID is a Note.
   static bool isBuiltinNote(unsigned DiagID);
 
@@ -260,11 +251,9 @@
   getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
                      const DiagnosticsEngine &Diag) const LLVM_READONLY;
 
-  /// \brief An internal implementation helper used when \p DiagClass is
-  /// already known.
-  DiagnosticIDs::Level
-  getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, SourceLocation Loc,
-                     const DiagnosticsEngine &Diag) const LLVM_READONLY;
+  diag::Severity
+  getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
+                        const DiagnosticsEngine &Diag) const LLVM_READONLY;
 
   /// \brief Used to report a diagnostic that is finally fully formed.
   ///
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index cb9236b..86def87 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -245,9 +245,9 @@
 // Preprocessor Diagnostics
 //===----------------------------------------------------------------------===//
 
-let CategoryName = "User Defined Issues" in {
+let CategoryName = "User-Defined Issue" in {
 def pp_hash_warning : Warning<"%0">,
-  InGroup<PoundWarning>, DefaultWarnShowInSystemHeader;
+  InGroup<PoundWarning>, ShowInSystemHeader;
 def err_pp_hash_error : Error<"%0">;
 }
 
@@ -500,7 +500,9 @@
   "pasting formed '%0', an invalid preprocessing token">, DefaultError,
   InGroup<DiagGroup<"invalid-token-paste">>;
 def err_pp_operator_used_as_macro_name : Error<
-  "C++ operator '%0' (aka %1) cannot be used as a macro name">;
+  "C++ operator %0 (aka %1) used as a macro name">;
+def ext_pp_operator_used_as_macro_name : Extension<
+  "C++ operator %0 (aka %1) used as a macro name">, InGroup<Microsoft>;
 def err_pp_illegal_floating_literal : Error<
   "floating point literal in preprocessor expression">;
 def err_pp_line_requires_integer : Error<
@@ -540,6 +542,10 @@
 def err_pp_eof_in_arc_cf_code_audited : Error<
   "'#pragma clang arc_cf_code_audited' was not ended within this file">;
 
+def warn_pp_date_time : Warning<
+  "expansion of date or time macro is not reproducible">,
+  ShowInSystemHeader, DefaultIgnore, InGroup<DiagGroup<"date-time">>;
+
 // Module map parsing
 def err_mmap_unknown_token : Error<"skipping stray token">;
 def err_mmap_expected_module : Error<"expected module declaration">;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 6a01dfc..69e2fb3 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -277,6 +277,13 @@
 def warn_cxx98_compat_for_range : Warning<
   "range-based for loop is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
+def ext_for_range_identifier : ExtWarn<
+  "range-based for loop with implicit deduced type is a C++1z extension">,
+  InGroup<CXX1z>;
+def warn_cxx1y_compat_for_range_identifier : Warning<
+  "range-based for loop with implicit deduced type is incompatible with "
+  "C++ standards before C++1z">,
+  InGroup<CXXPre1zCompat>, DefaultIgnore;
 def err_for_range_expected_decl : Error<
   "for range declaration must declare a variable">;
 def err_argument_required_after_attribute : Error<
@@ -333,8 +340,6 @@
   "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
 def err_friend_invalid_in_context : Error<
   "'friend' used outside of class">;
-def err_unknown_typename : Error<
-  "unknown type name %0">;
 def err_use_of_tag_name_without_tag : Error<
   "must use '%1' tag to refer to type %0%select{| in this scope}2">;
 def err_templated_using_directive : Error<
@@ -443,6 +448,8 @@
   "cannot use %select{dot|arrow}0 operator on a type">;
 def err_expected_unqualified_id : Error<
   "expected %select{identifier|unqualified-id}0">;
+def err_brackets_go_after_unqualified_id : Error<
+  "brackets go after the %select{identifier|unqualified-id}0">;
 def err_unexpected_unqualified_id : Error<"type-id cannot have a name">;
 def err_func_def_no_params : Error<
   "function definition does not declare parameters">;
@@ -566,6 +573,13 @@
   "expected ',' or '>' in template-parameter-list">;
 def err_class_on_template_template_param : Error<
   "template template parameter requires 'class' after the parameter list">;
+def ext_template_template_param_typename : ExtWarn<
+  "template template parameter using 'typename' is a C++1z extension">,
+  InGroup<CXX1z>;
+def warn_cxx1y_compat_template_template_param_typename : Warning<
+  "template template parameter using 'typename' is "
+  "incompatible with C++ standards before C++1z">,
+  InGroup<CXXPre1zCompat>, DefaultIgnore;
 def err_template_spec_syntax_non_template : Error<
   "identifier followed by '<' indicates a class template specialization but "
   "%0 %select{does not refer to a template|refers to a function template|"
@@ -892,6 +906,13 @@
   "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
 def err_omp_more_one_clause : Error<
   "directive '#pragma omp %0' cannot contain more than one '%1' clause">;
+
+// Pragma loop support.
+def err_pragma_loop_invalid_option : Error<
+  "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
+  "vectorize_width, interleave, interleave_count, unroll, or unroll_count">;
+def err_pragma_loop_missing_argument : Error<
+  "missing argument to loop pragma %0">;
 } // end of Parse Issue category.
 
 let CategoryName = "Modules Issue" in {
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 0215486..5ab9aef 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -14,6 +14,11 @@
 let Component = "Sema" in {
 let CategoryName = "Semantic Issue" in {
 
+def note_previous_decl : Note<"%0 declared here">;
+def note_entity_declared_at : Note<"%0 declared here">;
+def note_callee_decl : Note<"%0 declared here">;
+def note_defined_here : Note<"%0 defined here">;
+
 // For loop analysis
 def warn_variables_not_in_loop_body : Warning<
   "variable%select{s| %1|s %1 and %2|s %1, %2, and %3|s %1, %2, %3, and %4}0 "
@@ -406,8 +411,8 @@
   InGroup<ImplicitFunctionDeclare>, DefaultError;
 def warn_dyn_class_memaccess : Warning<
   "%select{destination for|source of|first operand of|second operand of}0 this "
-  "%1 call is a pointer to dynamic class %2; vtable pointer will be "
-  "%select{overwritten|copied|moved|compared}3">,
+  "%1 call is a pointer to %select{|class containing a }2dynamic class %3; "
+  "vtable pointer will be %select{overwritten|copied|moved|compared}4">,
   InGroup<DiagGroup<"dynamic-class-memaccess">>;
 def note_bad_memaccess_silence : Note<
   "explicitly cast the pointer to silence this warning">;
@@ -537,6 +542,15 @@
   "#pragma visibility pop with no matching #pragma visibility push">;
 def note_surrounding_namespace_starts_here : Note<
   "surrounding namespace with visibility attribute starts here">;
+def err_pragma_loop_invalid_value : Error<
+  "invalid argument; expected a positive integer value">;
+def err_pragma_loop_invalid_keyword : Error<
+  "invalid argument; expected 'enable' or 'disable'">;
+def err_pragma_loop_compatibility : Error<
+  "%select{incompatible|duplicate}0 directives '%1(%2)' and '%3(%4)'">;
+def err_pragma_loop_precedes_nonloop : Error<
+  "expected a for, while, or do-while loop to follow the '#pragma clang loop' "
+  "directive">;
 
 /// Objective-C parser diagnostics
 def err_duplicate_class_def : Error<
@@ -917,7 +931,12 @@
 // C++ declarations
 def err_static_assert_expression_is_not_constant : Error<
   "static_assert expression is not an integral constant expression">;
-def err_static_assert_failed : Error<"static_assert failed %0">;
+def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;
+def ext_static_assert_no_message : ExtWarn<
+  "static_assert with no message is a C++1z extension">, InGroup<CXX1z>;
+def warn_cxx1y_compat_static_assert_no_message : Warning<
+  "static_assert with no message is incompatible with C++ standards before C++1z">,
+  DefaultIgnore, InGroup<CXXPre1zCompat>;
 
 def warn_inline_namespace_reopened_noninline : Warning<
   "inline namespace cannot be reopened as a non-inline namespace">;
@@ -1222,10 +1241,9 @@
   "call to pure virtual member function %0; overrides of %0 in subclasses are "
   "not available in the %select{constructor|destructor}1 of %2">;
 
-def note_field_decl : Note<"member is declared here">;
+def note_member_declared_at : Note<"member is declared here">;
 def note_ivar_decl : Note<"instance variable is declared here">;
 def note_bitfield_decl : Note<"bit-field is declared here">;
-def note_previous_decl : Note<"%0 declared here">;
 def note_implicit_param_decl : Note<"%0 is an implicit parameter">;
 def note_member_synthesized_at : Note<
   "implicit %select{default constructor|copy constructor|move constructor|copy "
@@ -1486,6 +1504,9 @@
   InGroup<Uninitialized>, DefaultIgnore;
 def note_block_var_fixit_add_initialization : Note<
   "maybe you meant to use __block %0">;
+def note_in_omitted_aggregate_initializer : Note<
+  "in implicit initialization of %select{array element %1|field %1}0 "
+  "with omitted initializer">;
 def note_var_fixit_add_initialization : Note<
   "initialize the variable %0 to silence this warning">;
 def note_uninit_fixit_remove_cond : Note<
@@ -1670,6 +1691,8 @@
   "not 'enum class'">;
 def err_only_enums_have_underlying_types : Error<
   "only enumeration types have underlying types">;
+def err_underlying_type_of_incomplete_enum : Error<
+  "cannot determine underlying type of incomplete enumeration type %0">;
 
 // C++11 delegating constructors
 def err_delegating_ctor : Error<
@@ -2004,6 +2027,9 @@
   "use 'isEqual:' instead">;
 def err_attribute_argument_is_zero : Error<
   "%0 attribute must be greater than 0">;
+def err_property_function_in_objc_container : Error<
+  "use of Objective-C property in function nested in Objective-C "
+  "container not supported, move function outside its container">;
 
 let CategoryName = "Cocoa API Issue" in {
 def warn_objc_redundant_literal_use : Warning<
@@ -2093,8 +2119,26 @@
   "redeclaration of %q0 cannot add %q1 attribute">;
 def err_attribute_dllimport_function_definition : Error<
   "dllimport cannot be applied to non-inline function definition">;
+def err_attribute_dll_deleted : Error<
+  "attribute %q0 cannot be applied to a deleted function">;
 def err_attribute_dllimport_data_definition : Error<
   "definition of dllimport data">;
+def err_attribute_dllimport_static_field_definition : Error<
+  "definition of dllimport static field not allowed">;
+def warn_attribute_dllimport_static_field_definition : Warning<
+  "definition of dllimport static field">,
+  InGroup<DiagGroup<"dllimport-static-field-def">>;
+def warn_invalid_initializer_from_system_header : Warning<
+  "invalid constructor form class in system header, should not be explicit">,
+  InGroup<DiagGroup<"invalid-initializer-from-system-header">>;
+def note_used_in_initialization_here : Note<"used in initialization here">;
+def err_attribute_dll_member_of_dll_class : Error<
+  "attribute %q0 cannot be applied to member of %q1 class">;
+def warn_attribute_dll_instantiated_base_class : Warning<
+  "propagating dll attribute to %select{already instantiated|explicitly specialized}0 "
+  "base class template "
+  "%select{without dll attribute|with different dll attribute}1 is unsupported">,
+  InGroup<DiagGroup<"unsupported-dll-base-class-template">>;
 def err_attribute_weakref_not_static : Error<
   "weakref declaration must have internal linkage">;
 def err_attribute_weakref_not_global_context : Error<
@@ -2372,10 +2416,28 @@
     "address of%select{| function| array}0 '%1' will always evaluate to "
     "'true'">,
     InGroup<PointerBoolConversion>;
+def warn_this_bool_conversion : Warning<
+  "'this' pointer cannot be null in well-defined C++ code; pointer may be "
+  "assumed to always convert to true">, InGroup<UndefinedBoolConversion>;
+def warn_address_of_reference_bool_conversion : Warning<
+  "reference cannot be bound to dereferenced null pointer in well-defined C++ "
+  "code; pointer may be assumed to always convert to true">,
+  InGroup<UndefinedBoolConversion>;
+
 def warn_null_pointer_compare : Warning<
     "comparison of %select{address of|function|array}0 '%1' %select{not |}2"
     "equal to a null pointer is always %select{true|false}2">,
     InGroup<TautologicalPointerCompare>;
+def warn_this_null_compare : Warning<
+  "'this' pointer cannot be null in well-defined C++ code; comparison may be "
+  "assumed to always evaluate to %select{true|false}0">,
+  InGroup<TautologicalUndefinedCompare>;
+def warn_address_of_reference_null_compare : Warning<
+  "reference cannot be bound to dereferenced null pointer in well-defined C++ "
+  "code; comparison may be assumed to always evaluate to "
+  "%select{true|false}0">,
+  InGroup<TautologicalUndefinedCompare>;
+def note_reference_is_return_value : Note<"%0 returns a reference">;
 
 def note_function_warning_silence : Note<
     "prefix with the address-of operator to silence this warning">;
@@ -2436,6 +2498,7 @@
   InGroup<DiagGroup<"unsupported-visibility">>;
 def err_mismatched_visibility: Error<"visibility does not match previous declaration">;
 def note_previous_attribute : Note<"previous attribute is here">;
+def note_attribute : Note<"attribute is here">;
 def err_mismatched_ms_inheritance : Error<
   "inheritance model does not match %select{definition|previous declaration}0">;
 def warn_ignored_ms_inheritance : Warning<
@@ -3061,11 +3124,14 @@
   "%select{class template|function template|template template parameter"
   "|template}1 %2">;
 def note_template_decl_here : Note<"template is declared here">;
-def note_member_of_template_here : Note<"member is declared here">;
 def err_template_arg_must_be_type : Error<
   "template argument for template type parameter must be a type">;
 def err_template_arg_must_be_type_suggest : Error<
   "template argument for template type parameter must be a type; did you forget 'typename'?">;
+def ext_ms_template_type_arg_missing_typename : ExtWarn<
+  "template argument for template type parameter must be a type; "
+  "omitted 'typename' is a Microsoft extension">,
+  InGroup<Microsoft>;
 def err_template_arg_must_be_expr : Error<
   "template argument for non-type template parameter must be an expression">;
 def err_template_arg_nontype_ambig : Error<
@@ -3179,6 +3245,9 @@
 def ext_ms_deref_template_argument: ExtWarn<
   "non-type template argument containing a dereference operation is a "
   "Microsoft extension">, InGroup<Microsoft>;
+def ext_ms_delayed_template_argument: ExtWarn<
+  "using the undeclared type %0 as a default template argument is a "
+  "Microsoft extension">, InGroup<Microsoft>;
 
 // C++ template specialization
 def err_template_spec_unknown_kind : Error<
@@ -3346,6 +3415,10 @@
   "%select{implicit|explicit}0 instantiation of undefined template %1">;
 def err_implicit_instantiate_member_undefined : Error<
   "implicit instantiation of undefined member %0">;
+def note_template_class_instantiation_was_here : Note<
+  "class template %0 was instantiated here">;
+def note_template_class_explicit_specialization_was_here : Note<
+  "class template %0 was explicitly specialized here">;
 def note_template_class_instantiation_here : Note<
   "in instantiation of template class %0 requested here">;
 def note_template_member_class_here : Note<
@@ -3496,7 +3569,7 @@
     "referenced member %0 is declared here">;
 def err_typename_missing : Error<
   "missing 'typename' prior to dependent type name '%0%1'">;
-def warn_typename_missing : ExtWarn<
+def ext_typename_missing : ExtWarn<
   "missing 'typename' prior to dependent type name '%0%1'">,
   InGroup<DiagGroup<"typename-missing">>;
 def ext_typename_outside_of_template : ExtWarn<
@@ -3610,9 +3683,13 @@
 def err_unexpected_namespace : Error<
   "unexpected namespace name %0: expected expression">;
 def err_undeclared_var_use : Error<"use of undeclared identifier %0">;
-def warn_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 "
-   "found via unqualified lookup into dependent bases of class templates is a "
-   "Microsoft extension">, InGroup<Microsoft>;
+def ext_undeclared_unqual_id_with_dependent_base : ExtWarn<
+  "use of undeclared identifier %0; "
+  "unqualified lookup into dependent bases of class template %1 is a Microsoft extension">,
+  InGroup<Microsoft>;
+def ext_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 "
+  "found via unqualified lookup into dependent bases of class templates is a "
+  "Microsoft extension">, InGroup<Microsoft>;
 def note_dependent_var_use : Note<"must qualify identifier to find this "
     "declaration in dependent base class">;
 def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither "
@@ -3622,6 +3699,9 @@
 def err_undeclared_use : Error<"use of undeclared %0">;
 def warn_deprecated : Warning<"%0 is deprecated">,
     InGroup<DeprecatedDeclarations>;
+def warn_property_method_deprecated :
+    Warning<"property access is using %0 method which is deprecated">,
+    InGroup<DeprecatedDeclarations>;
 def warn_deprecated_message : Warning<"%0 is deprecated: %1">,
     InGroup<DeprecatedDeclarations>;
 def warn_deprecated_fwdclass_message : Warning<
@@ -3631,6 +3711,8 @@
     "Implementing deprecated %select{method|class|category}0">,
     InGroup<DeprecatedImplementations>, DefaultIgnore;
 def err_unavailable : Error<"%0 is unavailable">;
+def err_property_method_unavailable :
+    Error<"property access is using %0 method which is unavailable">;
 def err_unavailable_message : Error<"%0 is unavailable: %1">;
 def warn_unavailable_fwdclass_message : Warning<
     "%0 may be unavailable because the receiver type is unknown">,
@@ -3726,8 +3808,6 @@
   "in different files">, InGroup<StaticLocalInInline>;
 def note_convert_inline_to_static : Note<
   "use 'static' to give inline function %0 internal linkage">;
-def note_internal_decl_declared_here : Note<
-  "%0 declared here">;
 
 def warn_redefinition_of_typedef : ExtWarn<
   "redefinition of typedef %0 is a C11 feature">,
@@ -3753,8 +3833,8 @@
   "declared %select{in global scope|with C language linkage}0 here">;
 def warn_weak_import : Warning <
   "an already-declared variable is made a weak_import declaration %0">;
-def warn_static_non_static : ExtWarn<
-  "static declaration of %0 follows non-static declaration">;
+def ext_static_non_static : Extension<
+  "redeclaring non-static %0 as static is a Microsoft extension">, InGroup<Microsoft>;
 def err_non_static_static : Error<
   "non-static declaration of %0 follows static declaration">;
 def err_extern_non_extern : Error<
@@ -4457,7 +4537,7 @@
   "'%1' will be evaluated first">, InGroup<ShiftOpParentheses>;
 
 def warn_self_assignment : Warning<
-  "explicitly assigning a variable of type %0 to itself">,
+  "explicitly assigning value of variable of type %0 to itself">,
   InGroup<SelfAssignment>, DefaultIgnore;
 
 def warn_string_plus_int : Warning<
@@ -5073,6 +5153,8 @@
   "you need to include <typeinfo> before using the 'typeid' operator">;
 def err_need_header_before_ms_uuidof : Error<
   "you need to include <guiddef.h> before using the '__uuidof' operator">;
+def err_ms___leave_not_in___try : Error<
+  "'__leave' statement not in __try block">;
 def err_uuidof_without_guid : Error<
   "cannot call operator __uuidof on a type with no GUID">;
 def err_uuidof_with_multiple_guids : Error<
@@ -5352,8 +5434,6 @@
   
 def err_expected_class_or_namespace : Error<"%0 is not a class"
   "%select{ or namespace|, namespace, or scoped enumeration}1">;
-def note_expected_class_or_namespace_declared_here : Note<
-  "%0 declared here">;
 def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here "
   "because namespace %1 does not enclose namespace %2">;
 def err_invalid_declarator_global_scope : Error<
@@ -5432,6 +5512,8 @@
   "return type must match previous return type}0,1 when %select{block "
   "literal|lambda expression}2 has unspecified explicit return type">;
 
+def not_incomplete_class_and_qualified_id : Note<
+  "conformance of forward class %0 to protocol %1 can not be confirmed">;
 def warn_incompatible_qualified_id : Warning<
   "%select{%diff{assigning to $ from incompatible type $|"
   "assigning to type from incompatible type}0,1"
@@ -5648,8 +5730,6 @@
   "calling function with incomplete return type %0">;
 def err_call_function_incomplete_return : Error<
   "calling %0 with incomplete return type %1">;
-def note_function_with_incomplete_return_type_declared_here : Note<
-  "%0 declared here">;
 def err_call_incomplete_argument : Error<
   "argument type %0 is incomplete">;
 def err_typecheck_call_too_few_args : Error<
@@ -5705,10 +5785,6 @@
   "incompatible pointer types passing retainable parameter of type %0"
   "to a CF function expecting %1 type">;
   
-def note_callee_decl : Note<
-  "%0 declared here">;
-def note_defined_here : Note<"%0 defined here">;
-
 def err_builtin_fn_use : Error<"builtin functions must be directly called">;
 
 def warn_call_wrong_number_of_arguments : Warning<
@@ -5824,6 +5900,10 @@
 def warn_cast_pointer_from_sel : Warning<
   "cast of type %0 to %1 is deprecated; use sel_getName instead">,
   InGroup<SelTypeCast>;
+def warn_function_def_in_objc_container : Warning<
+  "function definition inside an Objective-C container is deprecated">,
+  InGroup<FunctionDefInObjCContainer>;
+  
 def warn_bad_function_cast : Warning<
   "cast from function call of type %0 to non-matching type %1">,
   InGroup<BadFunctionCast>, DefaultIgnore;
@@ -5911,6 +5991,7 @@
     "%diff{$ matching output with type $|}0,1">;
   def err_asm_incomplete_type : Error<"asm operand has incomplete type %0">;
   def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
+  def err_asm_bad_register_type : Error<"bad type for named register variable">;
   def err_asm_invalid_input_size : Error<
     "invalid input size for constraint '%0'">;
   def err_invalid_asm_cast_lvalue : Error<
@@ -6060,8 +6141,6 @@
 def err_reference_to_local_var_in_enclosing_context : Error<
   "reference to local variable %0 declared in enclosing context">;
 
-def note_local_variable_declared_here : Note<
-  "%0 declared here">;
 def err_static_data_member_not_allowed_in_local_class : Error<
   "static data member %0 not allowed in local class %1">; 
   
@@ -6287,12 +6366,13 @@
 def warn_scanf_nonzero_width : Warning<
   "zero field width in scanf format string is unused">,
   InGroup<Format>;
-def warn_printf_conversion_argument_type_mismatch : Warning<
-  "format specifies type %0 but the argument has type %1">,
+def warn_format_conversion_argument_type_mismatch : Warning<
+  "format specifies type %0 but the argument has "
+  "%select{type|underlying type}2 %1">,
   InGroup<Format>;
 def warn_format_argument_needs_cast : Warning<
-  "values of type '%0' should not be used as format arguments; add an explicit "
-  "cast to %1 instead">,
+  "%select{values of type|enum values with underlying type}2 '%0' should not "
+  "be used as format arguments; add an explicit cast to %1 instead">,
   InGroup<Format>;
 def warn_printf_positional_arg_exceeds_data_args : Warning <
   "data argument position '%0' exceeds the number of data arguments (%1)">,
@@ -6670,9 +6750,20 @@
   "incompatible constant for this __builtin_neon function">; 
 def err_argument_invalid_range : Error<
   "argument should be a value from %0 to %1">;
+def warn_neon_vector_initializer_non_portable : Warning<
+  "vector initializers are not compatible with NEON intrinsics in big endian "
+  "mode">, InGroup<DiagGroup<"nonportable-vector-initialization">>;
+def note_neon_vector_initializer_non_portable : Note<
+  "consider using vld1_%0%1() to initialize a vector from memory, or "
+  "vcreate_%0%1() to initialize from an integer constant">;
+def note_neon_vector_initializer_non_portable_q : Note<
+  "consider using vld1q_%0%1() to initialize a vector from memory, or "
+  "vcombine_%0%1(vcreate_%0%1(), vcreate_%0%1()) to initialize from integer "
+  "constants">;
 
 def err_builtin_longjmp_invalid_val : Error<
   "argument to __builtin_longjmp must be a constant 1">;
+def err_builtin_requires_language : Error<"'%0' is only available in %1">;
 
 def err_constant_integer_arg_type : Error<
   "argument to %0 must be a constant integer">;
@@ -6770,6 +6861,8 @@
   "directly accessed">, InGroup<DiagGroup<"direct-ivar-access">>, DefaultIgnore;
 
 // Spell-checking diagnostics
+def err_unknown_typename : Error<
+  "unknown type name %0">;
 def err_unknown_type_or_class_name_suggest : Error<
   "unknown %select{type|class}1 name %0; did you mean %2?">;
 def err_unknown_typename_suggest : Error<
@@ -6910,6 +7003,10 @@
   "a private variable with incomplete type %0">;
 def err_omp_firstprivate_incomplete_type : Error<
   "a firstprivate variable with incomplete type %0">;
+def err_omp_lastprivate_incomplete_type : Error<
+  "a lastprivate variable with incomplete type %0">;
+def err_omp_reduction_incomplete_type : Error<
+  "a reduction variable with incomplete type %0">;
 def err_omp_unexpected_clause_value : Error<
   "expected %0 in OpenMP clause '%1'">;
 def err_omp_expected_var_name : Error<
@@ -6927,9 +7024,24 @@
 def note_omp_explicit_dsa : Note<
   "defined as %0">;
 def note_omp_predetermined_dsa : Note<
-  "predetermined as %0">;
+  "%select{static data member is predetermined as shared|"
+  "variable with static storage duration is predetermined as shared|"
+  "loop iteration variable is predetermined as private|"
+  "loop iteration variable is predetermined as linear|"
+  "loop iteration variable is predetermined as lastprivate|"
+  "constant variable is predetermined as shared|"
+  "global variable is predetermined as shared|"
+  "variable with automatic storage duration is predetermined as private}0"
+  "%select{|; perhaps you forget to enclose 'omp %2' directive into a parallel or another task region?}1">;
+def note_omp_implicit_dsa : Note<
+  "implicitly determined as %0">;
+def err_omp_loop_var_dsa : Error<
+  "loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2">;
 def err_omp_not_for : Error<
-  "statement after '#pragma omp %0' must be a for loop">;
+  "%select{statement after '#pragma omp %1' must be a for loop|"
+  "expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">;
+def note_omp_collapse_expr : Note<
+  "as specified in 'collapse' clause">;
 def err_omp_negative_expression_in_clause : Error<
   "argument to '%0' clause must be a positive integer value">;
 def err_omp_not_integral : Error<
@@ -6956,6 +7068,71 @@
 def warn_omp_linear_step_zero : Warning<
   "zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
   InGroup<OpenMPClauses>;
+def err_omp_aligned_expected_array_or_ptr : Error<
+  "argument of aligned clause should be array"
+  "%select{ or pointer|, pointer, reference to array or reference to pointer}1"
+  ", not %0">;
+def err_omp_aligned_twice : Error<
+  "a variable cannot appear in more than one aligned clause">;
+def err_omp_local_var_in_threadprivate_init : Error<
+  "variable with local storage in initial value of threadprivate variable">;
+def err_omp_loop_not_canonical_init : Error<
+  "initialization clause of OpenMP for loop must be of the form "
+  "'var = init' or 'T var = init'">;
+def ext_omp_loop_not_canonical_init : ExtWarn<
+  "initialization clause of OpenMP for loop is not in canonical form "
+  "('var = init' or 'T var = init')">, InGroup<OpenMPLoopForm>;
+def err_omp_loop_not_canonical_cond : Error<
+  "condition of OpenMP for loop must be a relational comparison "
+  "('<', '<=', '>', or '>=') of loop variable %0">;
+def err_omp_loop_not_canonical_incr : Error<
+  "increment clause of OpenMP for loop must perform simple addition "
+  "or subtraction on loop variable %0">;
+def err_omp_loop_variable_type : Error<
+  "variable must be of integer or %select{pointer|random access iterator}0 type">;
+def err_omp_loop_incr_not_compatible : Error<
+  "increment expression must cause %0 to %select{decrease|increase}1 "
+  "on each iteration of OpenMP for loop">;
+def note_omp_loop_cond_requres_compatible_incr : Note<
+  "loop step is expected to be %select{negative|positive}0 due to this condition">;
+def err_omp_loop_cannot_use_stmt : Error<
+  "'%0' statement cannot be used in OpenMP for loop">;
+def err_omp_simd_region_cannot_use_stmt : Error<
+  "'%0' statement cannot be used in OpenMP simd region">;
+def err_omp_unknown_reduction_identifier : Error<
+  "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">;
+def err_omp_reduction_type_array : Error<
+  "a reduction variable with array type %0">;
+def err_omp_reduction_ref_type_arg : Error<
+  "argument of OpenMP clause 'reduction' must reference the same object in all threads">;
+def err_omp_clause_not_arithmetic_type_arg : Error<
+  "arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of %select{scalar|arithmetic}0 type">;
+def err_omp_clause_floating_type_arg : Error<
+  "arguments of OpenMP clause 'reduction' with bitwise operators cannot be of floating type">;
+def err_omp_once_referenced : Error<
+  "variable can appear only once in OpenMP '%0' clause">;
+def note_omp_referenced : Note<
+  "previously referenced here">;
+def err_omp_reduction_in_task : Error<
+  "reduction variables may not be accessed in an explicit task">;
+def err_omp_reduction_id_not_compatible : Error<
+  "variable of type %0 is not valid for specified reduction operation">;
+def err_omp_prohibited_region : Error<
+  "region cannot be%select{| closely}0 nested inside '%1' region"
+  "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?}2">;
+def err_omp_prohibited_region_simd : Error<
+  "OpenMP constructs may not be nested inside a simd region">;
+def err_omp_sections_not_compound_stmt : Error<
+  "the statement for '#pragma omp sections' must be a compound statement">;
+def err_omp_parallel_sections_not_compound_stmt : Error<
+  "the statement for '#pragma omp parallel sections' must be a compound statement">;
+def err_omp_orphaned_section_directive : Error<
+  "%select{orphaned 'omp section' directives are prohibited, it|'omp section' directive}0"
+  " must be closely nested to a sections region%select{|, not a %1 region}0">;
+def err_omp_sections_substmt_not_section : Error<
+  "statement in 'omp sections' directive must be enclosed into a section region">;
+def err_omp_parallel_sections_substmt_not_section : Error<
+  "statement in 'omp parallel sections' directive must be enclosed into a section region">;
 } // end of OpenMP category
 
 let CategoryName = "Related Result Type Issue" in {
@@ -7019,6 +7196,10 @@
   "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1"
   " no data and %2 %plural{1:has|:have}2 mismatched data that will be ignored">,
   InGroup<ProfileInstrOutOfDate>;
+def warn_profile_data_unprofiled : Warning<
+  "no profile data available for file \"%0\"">,
+  InGroup<ProfileInstrUnprofiled>;
+
 } // end of instrumentation issue category
 
 } // end of sema component.
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index 023433b..dd1ad0d 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -172,7 +172,7 @@
   std::unique_ptr<FileSystemStatCache> StatCache;
 
   bool getStatValue(const char *Path, FileData &Data, bool isFile,
-                    vfs::File **F);
+                    std::unique_ptr<vfs::File> *F);
 
   /// Add all ancestors of the given path (pointing to either a file
   /// or a directory) as virtual directories.
@@ -242,7 +242,8 @@
   /// MemoryBuffer if successful, otherwise returning null.
   llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry,
                                        std::string *ErrorStr = nullptr,
-                                       bool isVolatile = false);
+                                       bool isVolatile = false,
+                                       bool ShouldCloseOpenFile = true);
   llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
                                        std::string *ErrorStr = nullptr);
 
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index af25356..9be8b10 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -19,8 +19,6 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/FileSystem.h"
 #include <memory>
-#include <sys/stat.h>
-#include <sys/types.h>
 
 namespace clang {
 
@@ -71,7 +69,7 @@
   /// implementation can optionally fill in \p F with a valid \p File object and
   /// the client guarantees that it will close it.
   static bool get(const char *Path, FileData &Data, bool isFile,
-                  vfs::File **F, FileSystemStatCache *Cache,
+                  std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
                   vfs::FileSystem &FS);
 
   /// \brief Sets the next stat call cache in the chain of stat caches.
@@ -89,11 +87,15 @@
   FileSystemStatCache *takeNextStatCache() { return NextStatCache.release(); }
 
 protected:
+  // FIXME: The pointer here is a non-owning/optional reference to the
+  // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
+  // Optional needs some work to support references so this isn't possible yet.
   virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                               vfs::File **F, vfs::FileSystem &FS) = 0;
+                               std::unique_ptr<vfs::File> *F,
+                               vfs::FileSystem &FS) = 0;
 
   LookupResult statChained(const char *Path, FileData &Data, bool isFile,
-                           vfs::File **F, vfs::FileSystem &FS) {
+                           std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
     if (FileSystemStatCache *Next = getNextStatCache())
       return Next->getStat(Path, Data, isFile, F, FS);
 
@@ -118,7 +120,8 @@
   iterator end() const { return StatCalls.end(); }
 
   LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                       vfs::File **F, vfs::FileSystem &FS) override;
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override;
 };
 
 } // end namespace clang
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index 01898f4..5a71fa8 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 /// \file
-/// \brief Forward declares and imports various common LLVM datatypes that
+/// \brief Forward-declares and imports various common LLVM datatypes that
 /// clang wants to use unqualified.
 ///
 //===----------------------------------------------------------------------===//
@@ -29,6 +29,7 @@
   class StringRef;
   class Twine;
   template<typename T> class ArrayRef;
+  template<typename T> class MutableArrayRef;
   template<unsigned InternalLen> class SmallString;
   template<typename T, unsigned N> class SmallVector;
   template<typename T> class SmallVectorImpl;
@@ -62,6 +63,7 @@
   using llvm::StringRef;
   using llvm::Twine;
   using llvm::ArrayRef;
+  using llvm::MutableArrayRef;
   using llvm::SmallString;
   using llvm::SmallVector;
   using llvm::SmallVectorImpl;
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 0752eeb..0ac35a2 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -50,6 +50,7 @@
 LANGOPT(CPlusPlus         , 1, 0, "C++")
 LANGOPT(CPlusPlus11       , 1, 0, "C++11")
 LANGOPT(CPlusPlus1y       , 1, 0, "C++1y")
+LANGOPT(CPlusPlus1z       , 1, 0, "C++1z")
 LANGOPT(ObjC1             , 1, 0, "Objective-C 1")
 LANGOPT(ObjC2             , 1, 0, "Objective-C 2")
 BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
@@ -83,6 +84,7 @@
 LANGOPT(SjLjExceptions    , 1, 0, "setjmp-longjump exception handling")
 LANGOPT(TraditionalCPP    , 1, 0, "traditional CPP emulation")
 LANGOPT(RTTI              , 1, 1, "run-time type information")
+LANGOPT(RTTIData          , 1, 1, "emit run-time type information data")
 LANGOPT(MSBitfields       , 1, 0, "Microsoft-compatible structure layout")
 LANGOPT(Freestanding, 1, 0, "freestanding implementation")
 LANGOPT(NoBuiltin         , 1, 0, "disable builtin functions")
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index e969161..9bffc7c 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -19,7 +19,6 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/Visibility.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include <string>
 
 namespace clang {
@@ -53,7 +52,7 @@
 
 /// \brief Keeps track of the various options that can be
 /// enabled, which controls the dialect of C or C++ that is accepted.
-class LangOptions : public RefCountedBase<LangOptions>, public LangOptionsBase {
+class LangOptions : public LangOptionsBase {
 public:
   typedef clang::Visibility Visibility;
   
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 89fd388..9b66840 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -425,6 +425,10 @@
 
   /// \brief Determine whether the specified module would be visible to
   /// a lookup at the end of this module.
+  ///
+  /// FIXME: This may return incorrect results for (submodules of) the
+  /// module currently being built, if it's queried before we see all
+  /// of its imports.
   bool isModuleVisible(const Module *M) const {
     if (VisibleModulesCache.empty())
       buildVisibleModulesCache();
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 0adc984..691d13a 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -15,6 +15,9 @@
 #ifndef OPENMP_DIRECTIVE
 #  define OPENMP_DIRECTIVE(Name)
 #endif
+#ifndef OPENMP_DIRECTIVE_EXT
+#define OPENMP_DIRECTIVE_EXT(Name, Str)
+#endif
 #ifndef OPENMP_CLAUSE
 #  define OPENMP_CLAUSE(Name, Class)
 #endif
@@ -24,18 +27,42 @@
 #ifndef OPENMP_SIMD_CLAUSE
 #  define OPENMP_SIMD_CLAUSE(Name)
 #endif
+#ifndef OPENMP_FOR_CLAUSE
+#  define OPENMP_FOR_CLAUSE(Name)
+#endif
+#ifndef OPENMP_SECTIONS_CLAUSE
+#  define OPENMP_SECTIONS_CLAUSE(Name)
+#endif
+#ifndef OPENMP_SINGLE_CLAUSE
+#  define OPENMP_SINGLE_CLAUSE(Name)
+#endif
+#ifndef OPENMP_PARALLEL_FOR_CLAUSE
+#  define OPENMP_PARALLEL_FOR_CLAUSE(Name)
+#endif
+#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE
+#  define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)
+#endif
 #ifndef OPENMP_DEFAULT_KIND
 #  define OPENMP_DEFAULT_KIND(Name)
 #endif
 #ifndef OPENMP_PROC_BIND_KIND
 #  define OPENMP_PROC_BIND_KIND(Name)
 #endif
+#ifndef OPENMP_SCHEDULE_KIND
+#define OPENMP_SCHEDULE_KIND(Name)
+#endif
 
 // OpenMP directives.
 OPENMP_DIRECTIVE(threadprivate)
 OPENMP_DIRECTIVE(parallel)
 OPENMP_DIRECTIVE(task)
 OPENMP_DIRECTIVE(simd)
+OPENMP_DIRECTIVE(for)
+OPENMP_DIRECTIVE(sections)
+OPENMP_DIRECTIVE(section)
+OPENMP_DIRECTIVE(single)
+OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
+OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
 
 // OpenMP clauses.
 OPENMP_CLAUSE(if, OMPIfClause)
@@ -45,10 +72,17 @@
 OPENMP_CLAUSE(default, OMPDefaultClause)
 OPENMP_CLAUSE(private, OMPPrivateClause)
 OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
+OPENMP_CLAUSE(lastprivate, OMPLastprivateClause)
 OPENMP_CLAUSE(shared,  OMPSharedClause)
+OPENMP_CLAUSE(reduction,  OMPReductionClause)
 OPENMP_CLAUSE(linear,  OMPLinearClause)
+OPENMP_CLAUSE(aligned, OMPAlignedClause)
 OPENMP_CLAUSE(copyin,  OMPCopyinClause)
+OPENMP_CLAUSE(copyprivate,  OMPCopyprivateClause)
 OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
+OPENMP_CLAUSE(schedule, OMPScheduleClause)
+OPENMP_CLAUSE(ordered, OMPOrderedClause)
+OPENMP_CLAUSE(nowait, OMPNowaitClause)
 
 // Clauses allowed for OpenMP directive 'parallel'.
 OPENMP_PARALLEL_CLAUSE(if)
@@ -58,13 +92,40 @@
 OPENMP_PARALLEL_CLAUSE(private)
 OPENMP_PARALLEL_CLAUSE(firstprivate)
 OPENMP_PARALLEL_CLAUSE(shared)
+OPENMP_PARALLEL_CLAUSE(reduction)
 OPENMP_PARALLEL_CLAUSE(copyin)
 
-// FIXME: more clauses allowed for directive 'omp simd'.
+// Clauses allowed for directive 'omp simd'.
 OPENMP_SIMD_CLAUSE(private)
+OPENMP_SIMD_CLAUSE(lastprivate)
 OPENMP_SIMD_CLAUSE(linear)
+OPENMP_SIMD_CLAUSE(aligned)
 OPENMP_SIMD_CLAUSE(safelen)
 OPENMP_SIMD_CLAUSE(collapse)
+OPENMP_SIMD_CLAUSE(reduction)
+
+// TODO more clauses allowed for directive 'omp for'.
+OPENMP_FOR_CLAUSE(private)
+OPENMP_FOR_CLAUSE(lastprivate)
+OPENMP_FOR_CLAUSE(firstprivate)
+OPENMP_FOR_CLAUSE(reduction)
+OPENMP_FOR_CLAUSE(collapse)
+OPENMP_FOR_CLAUSE(schedule)
+OPENMP_FOR_CLAUSE(ordered)
+OPENMP_FOR_CLAUSE(nowait)
+
+// Clauses allowed for OpenMP directive 'omp sections'.
+OPENMP_SECTIONS_CLAUSE(private)
+OPENMP_SECTIONS_CLAUSE(lastprivate)
+OPENMP_SECTIONS_CLAUSE(firstprivate)
+OPENMP_SECTIONS_CLAUSE(reduction)
+OPENMP_SECTIONS_CLAUSE(nowait)
+
+// TODO more clauses allowed for directive 'omp single'.
+OPENMP_SINGLE_CLAUSE(private)
+OPENMP_SINGLE_CLAUSE(firstprivate)
+OPENMP_SINGLE_CLAUSE(copyprivate)
+OPENMP_SINGLE_CLAUSE(nowait)
 
 // Static attributes for 'default' clause.
 OPENMP_DEFAULT_KIND(none)
@@ -75,10 +136,51 @@
 OPENMP_PROC_BIND_KIND(close)
 OPENMP_PROC_BIND_KIND(spread)
 
+// Static attributes for 'schedule' clause.
+OPENMP_SCHEDULE_KIND(static)
+OPENMP_SCHEDULE_KIND(dynamic)
+OPENMP_SCHEDULE_KIND(guided)
+OPENMP_SCHEDULE_KIND(auto)
+OPENMP_SCHEDULE_KIND(runtime)
+
+// Clauses allowed for OpenMP directive 'parallel for'.
+OPENMP_PARALLEL_FOR_CLAUSE(if)
+OPENMP_PARALLEL_FOR_CLAUSE(num_threads)
+OPENMP_PARALLEL_FOR_CLAUSE(default)
+OPENMP_PARALLEL_FOR_CLAUSE(proc_bind)
+OPENMP_PARALLEL_FOR_CLAUSE(private)
+OPENMP_PARALLEL_FOR_CLAUSE(firstprivate)
+OPENMP_PARALLEL_FOR_CLAUSE(shared)
+OPENMP_PARALLEL_FOR_CLAUSE(reduction)
+OPENMP_PARALLEL_FOR_CLAUSE(copyin)
+OPENMP_PARALLEL_FOR_CLAUSE(lastprivate)
+OPENMP_PARALLEL_FOR_CLAUSE(collapse)
+OPENMP_PARALLEL_FOR_CLAUSE(schedule)
+OPENMP_PARALLEL_FOR_CLAUSE(ordered)
+
+// Clauses allowed for OpenMP directive 'parallel sections'.
+OPENMP_PARALLEL_SECTIONS_CLAUSE(if)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(num_threads)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(default)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(proc_bind)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(private)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(firstprivate)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(shared)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate)
+
+#undef OPENMP_SCHEDULE_KIND
 #undef OPENMP_PROC_BIND_KIND
 #undef OPENMP_DEFAULT_KIND
 #undef OPENMP_DIRECTIVE
+#undef OPENMP_DIRECTIVE_EXT
 #undef OPENMP_CLAUSE
+#undef OPENMP_SINGLE_CLAUSE
+#undef OPENMP_SECTIONS_CLAUSE
 #undef OPENMP_PARALLEL_CLAUSE
+#undef OPENMP_PARALLEL_FOR_CLAUSE
+#undef OPENMP_PARALLEL_SECTIONS_CLAUSE
 #undef OPENMP_SIMD_CLAUSE
+#undef OPENMP_FOR_CLAUSE
 
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index 2ee246e..526cbb2 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -23,6 +23,8 @@
 enum OpenMPDirectiveKind {
 #define OPENMP_DIRECTIVE(Name) \
   OMPD_##Name,
+#define OPENMP_DIRECTIVE_EXT(Name, Str) \
+  OMPD_##Name,
 #include "clang/Basic/OpenMPKinds.def"
   OMPD_unknown
 };
@@ -52,6 +54,14 @@
   OMPC_PROC_BIND_unknown
 };
 
+/// \brief OpenMP attributes for 'schedule' clause.
+enum OpenMPScheduleClauseKind {
+#define OPENMP_SCHEDULE_KIND(Name) \
+  OMPC_SCHEDULE_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_SCHEDULE_unknown
+};
+
 OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
 const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind);
 
@@ -64,6 +74,43 @@
 bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
                                  OpenMPClauseKind CKind);
 
+/// \brief Checks if the specified directive is a directive with an associated
+/// loop construct.
+/// \param DKind Specified directive.
+/// \return true - the directive is a loop-associated directive like 'omp simd'
+/// or 'omp for' directive, otherwise - false.
+bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a worksharing directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a worksharing directive like 'omp for',
+/// otherwise - false.
+bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a parallel-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a parallel-like directive like 'omp
+/// parallel', otherwise - false.
+bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a simd directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a simd directive like 'omp simd',
+/// otherwise - false.
+bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified clause is one of private clauses like
+/// 'private', 'firstprivate', 'reduction' etc..
+/// \param Kind Clause kind.
+/// \return true - the clause is a private clause, otherwise - false.
+bool isOpenMPPrivate(OpenMPClauseKind Kind);
+
+/// \brief Checks if the specified clause is one of threadprivate clauses like
+/// 'threadprivate', 'copyin' or 'copyprivate'.
+/// \param Kind Clause kind.
+/// \return true - the clause is a threadprivate clause, otherwise - false.
+bool isOpenMPThreadPrivate(OpenMPClauseKind Kind);
+
 }
 
 #endif
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
index 64853f9..b7a9382 100644
--- a/include/clang/Basic/PlistSupport.h
+++ b/include/clang/Basic/PlistSupport.h
@@ -19,13 +19,7 @@
 namespace markup {
 typedef llvm::DenseMap<FileID, unsigned> FIDMap;
 
-static const char *PlistHeader =
-    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-    "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
-    "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
-    "<plist version=\"1.0\">\n";
-
-static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
+inline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
                    const SourceManager &SM, SourceLocation L) {
   FileID FID = SM.getFileID(SM.getExpansionLoc(L));
   FIDMap::iterator I = FIDs.find(FID);
@@ -35,7 +29,7 @@
   V.push_back(FID);
 }
 
-static unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
+inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
                        SourceLocation L) {
   FileID FID = SM.getFileID(SM.getExpansionLoc(L));
   FIDMap::const_iterator I = FIDs.find(FID);
@@ -43,43 +37,29 @@
   return I->second;
 }
 
-static raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
+inline raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
   for (unsigned i = 0; i < indent; ++i)
     o << ' ';
   return o;
 }
 
-static void EmitLocation(raw_ostream &o, const SourceManager &SM,
-                         const LangOptions &LangOpts, SourceLocation L,
-                         const FIDMap &FM, unsigned indent,
-                         bool extend = false) {
-  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM));
-
-  // Add in the length of the token, so that we cover multi-char tokens.
-  unsigned offset =
-      extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
-
-  Indent(o, indent) << "<dict>\n";
-  Indent(o, indent) << " <key>line</key><integer>"
-                    << Loc.getExpansionLineNumber() << "</integer>\n";
-  Indent(o, indent) << " <key>col</key><integer>"
-                    << Loc.getExpansionColumnNumber() + offset
-                    << "</integer>\n";
-  Indent(o, indent) << " <key>file</key><integer>" << GetFID(FM, SM, Loc)
-                    << "</integer>\n";
-  Indent(o, indent) << "</dict>\n";
+inline raw_ostream &EmitPlistHeader(raw_ostream &o) {
+  static const char *PlistHeader =
+      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+      "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
+      "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+      "<plist version=\"1.0\">\n";
+  return o << PlistHeader;
 }
 
-static inline void EmitRange(raw_ostream &o, const SourceManager &SM,
-                             const LangOptions &LangOpts, CharSourceRange R,
-                             const FIDMap &FM, unsigned indent) {
-  Indent(o, indent) << "<array>\n";
-  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1);
-  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange());
-  Indent(o, indent) << "</array>\n";
+inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) {
+  o << "<integer>";
+  o << value;
+  o << "</integer>";
+  return o;
 }
 
-static raw_ostream &EmitString(raw_ostream &o, StringRef s) {
+inline raw_ostream &EmitString(raw_ostream &o, StringRef s) {
   o << "<string>";
   for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
     char c = *I;
@@ -107,6 +87,35 @@
   o << "</string>";
   return o;
 }
+
+inline void EmitLocation(raw_ostream &o, const SourceManager &SM,
+                         const LangOptions &LangOpts, SourceLocation L,
+                         const FIDMap &FM, unsigned indent,
+                         bool extend = false) {
+  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM));
+
+  // Add in the length of the token, so that we cover multi-char tokens.
+  unsigned offset =
+      extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
+
+  Indent(o, indent) << "<dict>\n";
+  Indent(o, indent) << " <key>line</key>";
+  EmitInteger(o, Loc.getExpansionLineNumber()) << '\n';
+  Indent(o, indent) << " <key>col</key>";
+  EmitInteger(o, Loc.getExpansionColumnNumber() + offset) << '\n';
+  Indent(o, indent) << " <key>file</key>";
+  EmitInteger(o, GetFID(FM, SM, Loc)) << '\n';
+  Indent(o, indent) << "</dict>\n";
+}
+
+inline void EmitRange(raw_ostream &o, const SourceManager &SM,
+                      const LangOptions &LangOpts, CharSourceRange R,
+                      const FIDMap &FM, unsigned indent) {
+  Indent(o, indent) << "<array>\n";
+  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1);
+  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange());
+  Indent(o, indent) << "</array>\n";
+}
 }
 }
 
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index 94c4616..0ef39bc 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -40,13 +40,6 @@
 
 // AddressSanitizer
 SANITIZER("address", Address)
-// More features of AddressSanitizer that should be turned on explicitly.
-SANITIZER("init-order", InitOrder)
-SANITIZER("use-after-return", UseAfterReturn)
-SANITIZER("use-after-scope", UseAfterScope)
-
-SANITIZER_GROUP("address-full", AddressFull,
-                Address | InitOrder | UseAfterReturn | UseAfterScope)
 
 // MemorySanitizer
 SANITIZER("memory", Memory)
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index bea4890..bece66d 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -104,7 +104,7 @@
     ///
     /// This is owned by the ContentCache object.  The bits indicate
     /// whether the buffer is invalid.
-    mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer;
+    mutable llvm::PointerIntPair<llvm::MemoryBuffer *, 2> Buffer;
 
   public:
     /// \brief Reference to the file entry representing this ContentCache.
@@ -182,10 +182,10 @@
     ///   will be emitted at.
     ///
     /// \param Invalid If non-NULL, will be set \c true if an error occurred.
-    const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
-                                        const SourceManager &SM,
-                                        SourceLocation Loc = SourceLocation(),
-                                        bool *Invalid = nullptr) const;
+    llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
+                                  const SourceManager &SM,
+                                  SourceLocation Loc = SourceLocation(),
+                                  bool *Invalid = nullptr) const;
 
     /// \brief Returns the size of the content encapsulated by this
     /// ContentCache.
@@ -205,7 +205,7 @@
     /// this content cache.  This is used for performance analysis.
     llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
 
-    void setBuffer(const llvm::MemoryBuffer *B) {
+    void setBuffer(llvm::MemoryBuffer *B) {
       assert(!Buffer.getPointer() && "MemoryBuffer already set.");
       Buffer.setPointer(B);
       Buffer.setInt(false);
@@ -213,13 +213,11 @@
 
     /// \brief Get the underlying buffer, returning NULL if the buffer is not
     /// yet available.
-    const llvm::MemoryBuffer *getRawBuffer() const {
-      return Buffer.getPointer();
-    }
+    llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); }
 
     /// \brief Replace the existing buffer (which will be deleted)
     /// with the given buffer.
-    void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree = false);
+    void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree = false);
 
     /// \brief Determine whether the buffer itself is invalid.
     bool isBufferInvalid() const {
@@ -790,7 +788,7 @@
   ///
   /// This does no caching of the buffer and takes ownership of the
   /// MemoryBuffer, so only pass a MemoryBuffer to this once.
-  FileID createFileID(const llvm::MemoryBuffer *Buffer,
+  FileID createFileID(llvm::MemoryBuffer *Buffer,
                       SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
                       int LoadedID = 0, unsigned LoadedOffset = 0,
                       SourceLocation IncludeLoc = SourceLocation()) {
@@ -820,8 +818,8 @@
   ///
   /// \param Invalid If non-NULL, will be set \c true if an error
   /// occurs while retrieving the memory buffer.
-  const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
-                                                   bool *Invalid = nullptr);
+  llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
+                                             bool *Invalid = nullptr);
 
   /// \brief Override the contents of the given source file by providing an
   /// already-allocated buffer.
@@ -834,8 +832,7 @@
   /// \param DoNotFree If true, then the buffer will not be freed when the
   /// source manager is destroyed.
   void overrideFileContents(const FileEntry *SourceFile,
-                            const llvm::MemoryBuffer *Buffer,
-                            bool DoNotFree = false);
+                            llvm::MemoryBuffer *Buffer, bool DoNotFree = false);
 
   /// \brief Override the given source file with another one.
   ///
@@ -872,8 +869,8 @@
   ///
   /// If there is an error opening this buffer the first time, this
   /// manufactures a temporary buffer and returns a non-empty error string.
-  const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
-                                      bool *Invalid = nullptr) const {
+  llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+                                bool *Invalid = nullptr) const {
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile()) {
@@ -887,8 +884,7 @@
                                                         Invalid);
   }
 
-  const llvm::MemoryBuffer *getBuffer(FileID FID,
-                                      bool *Invalid = nullptr) const {
+  llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = nullptr) const {
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile()) {
@@ -1287,7 +1283,7 @@
   /// an expansion location, not at the spelling location.
   ///
   /// \returns The presumed location of the specified SourceLocation. If the
-  /// presumed location cannot be calculate (e.g., because \p Loc is invalid
+  /// presumed location cannot be calculated (e.g., because \p Loc is invalid
   /// or the file containing \p Loc has changed on disk), returns an invalid
   /// presumed location.
   PresumedLoc getPresumedLoc(SourceLocation Loc,
@@ -1557,7 +1553,7 @@
   }
 
 private:
-  const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
+  llvm::MemoryBuffer *getFakeBufferForRecovery() const;
   const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
 
   const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
@@ -1626,8 +1622,8 @@
                             bool isSystemFile = false);
 
   /// \brief Create a new ContentCache for the specified  memory buffer.
-  const SrcMgr::ContentCache*
-  createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
+  const SrcMgr::ContentCache *
+  createMemBufferContentCache(llvm::MemoryBuffer *Buf);
 
   FileID getFileIDSlow(unsigned SLocOffset) const;
   FileID getFileIDLocal(unsigned SLocOffset) const;
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 0f0f284..1b0ead9 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -170,6 +170,7 @@
 def SEHTryStmt : Stmt;
 def SEHExceptStmt : Stmt;
 def SEHFinallyStmt : Stmt;
+def SEHLeaveStmt : Stmt;
 def MSDependentExistsStmt : Stmt;
 
 // OpenCL Extensions.
@@ -179,3 +180,9 @@
 def OMPExecutableDirective : Stmt<1>;
 def OMPParallelDirective : DStmt<OMPExecutableDirective>;
 def OMPSimdDirective : DStmt<OMPExecutableDirective>;
+def OMPForDirective : DStmt<OMPExecutableDirective>;
+def OMPSectionsDirective : DStmt<OMPExecutableDirective>;
+def OMPSectionDirective : DStmt<OMPExecutableDirective>;
+def OMPSingleDirective : DStmt<OMPExecutableDirective>;
+def OMPParallelForDirective : DStmt<OMPExecutableDirective>;
+def OMPParallelSectionsDirective : DStmt<OMPExecutableDirective>;
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index 953f6bd..b1652be 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -1,4 +1,4 @@
-//===--- TargetBuiltins.h - Target specific builtin IDs -------------------===//
+//===--- TargetBuiltins.h - Target specific builtin IDs ---------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -72,6 +72,15 @@
     };
   }
 
+  /// \brief R600 builtins
+  namespace R600 {
+  enum {
+    LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+  #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+  #include "clang/Basic/BuiltinsR600.def"
+    LastTSBuiltin
+  };
+  }
 
   /// \brief X86 builtins
   namespace X86 {
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 29de915..f4dcc0e 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -47,7 +47,7 @@
 /// \brief Exposes information about the current target.
 ///
 class TargetInfo : public RefCountedBase<TargetInfo> {
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   llvm::Triple Triple;
 protected:
   // Target values set by the ctor of the actual target implementation.  Default
@@ -94,8 +94,9 @@
   /// \param Opts - The options to use to initialize the target. The target may
   /// modify the options to canonicalize the target feature information to match
   /// what the backend expects.
-  static TargetInfo* CreateTargetInfo(DiagnosticsEngine &Diags,
-                                      TargetOptions *Opts);
+  static TargetInfo *
+  CreateTargetInfo(DiagnosticsEngine &Diags,
+                   const std::shared_ptr<TargetOptions> &Opts);
 
   virtual ~TargetInfo();
 
@@ -105,10 +106,6 @@
     return *TargetOpts; 
   }
 
-  void setTargetOpts(TargetOptions *TargetOpts) {
-    this->TargetOpts = TargetOpts;
-  }
-
   ///===---- Target Data Type Query Methods -------------------------------===//
   enum IntType {
     NoInt = 0,
@@ -214,6 +211,9 @@
     return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
   }
   IntType getIntPtrType() const { return IntPtrType; }
+  IntType getUIntPtrType() const {
+    return getIntTypeByWidth(getTypeWidth(IntPtrType), false);
+  }
   IntType getWCharType() const { return WCharType; }
   IntType getWIntType() const { return WIntType; }
   IntType getChar16Type() const { return Char16Type; }
@@ -230,6 +230,9 @@
   /// \brief Return integer type with specified width.
   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
 
+  /// \brief Return the smallest integer type with at least the specified width.
+  IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
+
   /// \brief Return floating point type with specified width.
   RealType getRealTypeByWidth(unsigned BitWidth) const;
 
@@ -624,7 +627,7 @@
   ///
   /// Apply changes to the target information with respect to certain
   /// language options which change the target configuration.
-  virtual void setForcedLangOptions(LangOptions &Opts);
+  virtual void adjust(const LangOptions &Opts);
 
   /// \brief Get the default set of target features for the CPU;
   /// this should include all legal feature strings on the target.
@@ -632,9 +635,7 @@
   }
 
   /// \brief Get the ABI currently in use.
-  virtual const char *getABI() const {
-    return "";
-  }
+  virtual StringRef getABI() const { return StringRef(); }
 
   /// \brief Get the C++ ABI currently in use.
   TargetCXXABI getCXXABI() const {
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index d8a10a5..2c86c31 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -15,15 +15,13 @@
 #ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
 #define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
 
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include <string>
 #include <vector>
 
 namespace clang {
 
 /// \brief Options for controlling the target.
-class TargetOptions : public RefCountedBase<TargetOptions> {
+class TargetOptions {
 public:
   /// If given, the name of the target triple to compile for. If not given the
   /// target will be selected to match the host.
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 845a8b0..5d08833 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -701,6 +701,11 @@
 ANNOTATION(pragma_openmp)
 ANNOTATION(pragma_openmp_end)
 
+// Annotations for loop pragma directives #pragma clang loop ...
+// The lexer produces these so that they only take effect when the parser
+// handles #pragma loop ... directives.
+ANNOTATION(pragma_loop_hint)
+
 // Annotations for module import translated from #include etc.
 ANNOTATION(module_include)
 ANNOTATION(module_begin)
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
index 0a99496..36f78fd 100644
--- a/include/clang/Basic/VirtualFileSystem.h
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -89,16 +89,97 @@
   /// \brief Get the status of the file.
   virtual llvm::ErrorOr<Status> status() = 0;
   /// \brief Get the contents of the file as a \p MemoryBuffer.
-  virtual llvm::error_code
-  getBuffer(const Twine &Name, std::unique_ptr<llvm::MemoryBuffer> &Result,
-            int64_t FileSize = -1, bool RequiresNullTerminator = true,
-            bool IsVolatile = false) = 0;
+  virtual std::error_code getBuffer(const Twine &Name,
+                                    std::unique_ptr<llvm::MemoryBuffer> &Result,
+                                    int64_t FileSize = -1,
+                                    bool RequiresNullTerminator = true,
+                                    bool IsVolatile = false) = 0;
   /// \brief Closes the file.
-  virtual llvm::error_code close() = 0;
+  virtual std::error_code close() = 0;
   /// \brief Sets the name to use for this file.
   virtual void setName(StringRef Name) = 0;
 };
 
+namespace detail {
+/// \brief An interface for virtual file systems to provide an iterator over the
+/// (non-recursive) contents of a directory.
+struct DirIterImpl {
+  virtual ~DirIterImpl();
+  /// \brief Sets \c CurrentEntry to the next entry in the directory on success,
+  /// or returns a system-defined \c error_code.
+  virtual std::error_code increment() = 0;
+  Status CurrentEntry;
+};
+} // end namespace detail
+
+/// \brief An input iterator over the entries in a virtual path, similar to
+/// llvm::sys::fs::directory_iterator.
+class directory_iterator {
+  std::shared_ptr<detail::DirIterImpl> Impl; // Input iterator semantics on copy
+
+public:
+  directory_iterator(std::shared_ptr<detail::DirIterImpl> I) : Impl(I) {
+    assert(Impl.get() != nullptr && "requires non-null implementation");
+    if (!Impl->CurrentEntry.isStatusKnown())
+      Impl.reset(); // Normalize the end iterator to Impl == nullptr.
+  }
+
+  /// \brief Construct an 'end' iterator.
+  directory_iterator() { }
+
+  /// \brief Equivalent to operator++, with an error code.
+  directory_iterator &increment(std::error_code &EC) {
+    assert(Impl && "attempting to increment past end");
+    EC = Impl->increment();
+    if (EC || !Impl->CurrentEntry.isStatusKnown())
+      Impl.reset(); // Normalize the end iterator to Impl == nullptr.
+    return *this;
+  }
+
+  const Status &operator*() const { return Impl->CurrentEntry; }
+  const Status *operator->() const { return &Impl->CurrentEntry; }
+
+  bool operator==(const directory_iterator &RHS) const {
+    if (Impl && RHS.Impl)
+      return Impl->CurrentEntry.equivalent(RHS.Impl->CurrentEntry);
+    return !Impl && !RHS.Impl;
+  }
+  bool operator!=(const directory_iterator &RHS) const {
+    return !(*this == RHS);
+  }
+};
+
+class FileSystem;
+
+/// \brief An input iterator over the recursive contents of a virtual path,
+/// similar to llvm::sys::fs::recursive_directory_iterator.
+class recursive_directory_iterator {
+  typedef std::stack<directory_iterator, std::vector<directory_iterator>>
+      IterState;
+
+  FileSystem *FS;
+  std::shared_ptr<IterState> State; // Input iterator semantics on copy.
+
+public:
+  recursive_directory_iterator(FileSystem &FS, const Twine &Path,
+                               std::error_code &EC);
+  /// \brief Construct an 'end' iterator.
+  recursive_directory_iterator() { }
+
+  /// \brief Equivalent to operator++, with an error code.
+  recursive_directory_iterator &increment(std::error_code &EC);
+
+  const Status &operator*() const { return *State->top(); }
+  const Status *operator->() const { return &*State->top(); }
+
+  bool operator==(const recursive_directory_iterator &Other) const {
+    return State == Other.State; // identity
+  }
+  bool operator!=(const recursive_directory_iterator &RHS) const {
+    return !(*this == RHS);
+  }
+};
+
 /// \brief The virtual file system interface.
 class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem> {
 public:
@@ -107,16 +188,21 @@
   /// \brief Get the status of the entry at \p Path, if one exists.
   virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
   /// \brief Get a \p File object for the file at \p Path, if one exists.
-  virtual llvm::error_code openFileForRead(const Twine &Path,
-                                           std::unique_ptr<File> &Result) = 0;
+  virtual std::error_code openFileForRead(const Twine &Path,
+                                          std::unique_ptr<File> &Result) = 0;
 
   /// This is a convenience method that opens a file, gets its content and then
   /// closes the file.
-  llvm::error_code getBufferForFile(const Twine &Name,
-                                    std::unique_ptr<llvm::MemoryBuffer> &Result,
-                                    int64_t FileSize = -1,
-                                    bool RequiresNullTerminator = true,
-                                    bool IsVolatile = false);
+  std::error_code getBufferForFile(const Twine &Name,
+                                   std::unique_ptr<llvm::MemoryBuffer> &Result,
+                                   int64_t FileSize = -1,
+                                   bool RequiresNullTerminator = true,
+                                   bool IsVolatile = false);
+
+  /// \brief Get a directory_iterator for \p Dir.
+  /// \note The 'end' iterator is directory_iterator().
+  virtual directory_iterator dir_begin(const Twine &Dir,
+                                       std::error_code &EC) = 0;
 };
 
 /// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by
@@ -135,27 +221,28 @@
 /// system overrides the other(s).
 class OverlayFileSystem : public FileSystem {
   typedef SmallVector<IntrusiveRefCntPtr<FileSystem>, 1> FileSystemList;
-  typedef FileSystemList::reverse_iterator iterator;
-
   /// \brief The stack of file systems, implemented as a list in order of
   /// their addition.
   FileSystemList FSList;
 
-  /// \brief Get an iterator pointing to the most recently added file system.
-  iterator overlays_begin() { return FSList.rbegin(); }
-
-  /// \brief Get an iterator pointing one-past the least recently added file
-  /// system.
-  iterator overlays_end() { return FSList.rend(); }
-
 public:
   OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base);
   /// \brief Pushes a file system on top of the stack.
   void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
 
   llvm::ErrorOr<Status> status(const Twine &Path) override;
-  llvm::error_code openFileForRead(const Twine &Path,
-                                   std::unique_ptr<File> &Result) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
+
+  typedef FileSystemList::reverse_iterator iterator;
+  
+  /// \brief Get an iterator pointing to the most recently added file system.
+  iterator overlays_begin() { return FSList.rbegin(); }
+
+  /// \brief Get an iterator pointing one-past the least recently added file
+  /// system.
+  iterator overlays_end() { return FSList.rend(); }
 };
 
 /// \brief Get a globally unique ID for a virtual file or directory.
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
index 8f7ae57..f68ccea 100644
--- a/include/clang/Basic/arm_neon.td
+++ b/include/clang/Basic/arm_neon.td
@@ -11,139 +11,257 @@
 //  file will be generated.  See ARM document DUI0348B.
 //
 //===----------------------------------------------------------------------===//
+//
+// Each intrinsic is a subclass of the Inst class. An intrinsic can either
+// generate a __builtin_* call or it can expand to a set of generic operations.
+//
+// The operations are subclasses of Operation providing a list of DAGs, the
+// last of which is the return value. The available DAG nodes are documented
+// below.
+//
+//===----------------------------------------------------------------------===//
 
-class Op;
+// The base Operation class. All operations must subclass this.
+class Operation<list<dag> ops=[]> {
+  list<dag> Ops = ops;
+  bit Unavailable = 0;
+}
+// An operation that only contains a single DAG.
+class Op<dag op> : Operation<[op]>;
+// A shorter version of Operation - takes a list of DAGs. The last of these will
+// be the return value.
+class LOp<list<dag> ops> : Operation<ops>;
 
-def OP_NONE  : Op;
-def OP_UNAVAILABLE : Op;
-def OP_ADD   : Op;
-def OP_ADDL  : Op;
-def OP_ADDLHi : Op;
-def OP_ADDW  : Op;
-def OP_ADDWHi : Op;
-def OP_SUB   : Op;
-def OP_SUBL  : Op;
-def OP_SUBLHi : Op;
-def OP_SUBW  : Op;
-def OP_SUBWHi : Op;
-def OP_MUL   : Op;
-def OP_MLA   : Op;
-def OP_MLAL  : Op;
-def OP_MULLHi : Op;
-def OP_MULLHi_P64 : Op;
-def OP_MULLHi_N : Op;
-def OP_MLALHi : Op;
-def OP_MLALHi_N : Op;
-def OP_MLS   : Op;
-def OP_MLSL  : Op;
-def OP_MLSLHi : Op;
-def OP_MLSLHi_N : Op;
-def OP_MUL_N : Op;
-def OP_MLA_N : Op;
-def OP_MLS_N : Op;
-def OP_FMLA_N : Op;
-def OP_FMLS_N : Op;
-def OP_MLAL_N : Op;
-def OP_MLSL_N : Op;
-def OP_MUL_LN: Op;
-def OP_MULX_LN: Op;
-def OP_MULL_LN : Op;
-def OP_MULLHi_LN : Op;
-def OP_MLA_LN: Op;
-def OP_MLS_LN: Op;
-def OP_MLAL_LN : Op;
-def OP_MLALHi_LN : Op;
-def OP_MLSL_LN : Op;
-def OP_MLSLHi_LN : Op;
-def OP_QDMULL_LN : Op;
-def OP_QDMULLHi_LN : Op;
-def OP_QDMLAL_LN : Op;
-def OP_QDMLALHi_LN : Op;
-def OP_QDMLSL_LN : Op;
-def OP_QDMLSLHi_LN : Op;
-def OP_QDMULH_LN : Op;
-def OP_QRDMULH_LN : Op;
-def OP_FMS_LN : Op;
-def OP_FMS_LNQ : Op;
-def OP_TRN1  : Op;
-def OP_ZIP1  : Op;
-def OP_UZP1  : Op;
-def OP_TRN2  : Op;
-def OP_ZIP2  : Op;
-def OP_UZP2  : Op;
-def OP_EQ    : Op;
-def OP_GE    : Op;
-def OP_LE    : Op;
-def OP_GT    : Op;
-def OP_LT    : Op;
-def OP_NEG   : Op;
-def OP_NOT   : Op;
-def OP_AND   : Op;
-def OP_OR    : Op;
-def OP_XOR   : Op;
-def OP_ANDN  : Op;
-def OP_ORN   : Op;
-def OP_CAST  : Op;
-def OP_HI    : Op;
-def OP_LO    : Op;
-def OP_CONC  : Op;
-def OP_DUP   : Op;
-def OP_DUP_LN: Op;
-def OP_SEL   : Op;
-def OP_REV64 : Op;
-def OP_REV32 : Op;
-def OP_REV16 : Op;
-def OP_XTN : Op;
-def OP_SQXTUN : Op;
-def OP_QXTN : Op;
-def OP_VCVT_NA_HI : Op;
-def OP_VCVT_EX_HI : Op;
-def OP_VCVTX_HI : Op;
-def OP_REINT : Op;
-def OP_ADDHNHi : Op;
-def OP_RADDHNHi : Op;
-def OP_SUBHNHi : Op;
-def OP_RSUBHNHi : Op;
-def OP_ABDL  : Op;
-def OP_ABDLHi : Op;
-def OP_ABA   : Op;
-def OP_ABAL  : Op;
-def OP_ABALHi : Op;
-def OP_QDMULLHi : Op;
-def OP_QDMULLHi_N : Op;
-def OP_QDMLALHi : Op;
-def OP_QDMLALHi_N : Op;
-def OP_QDMLSLHi : Op;
-def OP_QDMLSLHi_N : Op;
-def OP_DIV  : Op;
-def OP_LONG_HI : Op;
-def OP_NARROW_HI : Op;
-def OP_MOVL_HI : Op;
-def OP_COPY_LN : Op;
-def OP_COPYQ_LN : Op;
-def OP_COPY_LNQ : Op;
-def OP_SCALAR_MUL_LN : Op;
-def OP_SCALAR_MUL_LNQ : Op;
-def OP_SCALAR_MULX_LN : Op;
-def OP_SCALAR_MULX_LNQ : Op;
-def OP_SCALAR_VMULX_LN : Op;
-def OP_SCALAR_VMULX_LNQ : Op;
-def OP_SCALAR_QDMULL_LN : Op;
-def OP_SCALAR_QDMULL_LNQ : Op;
-def OP_SCALAR_QDMULH_LN : Op;
-def OP_SCALAR_QDMULH_LNQ : Op;
-def OP_SCALAR_QRDMULH_LN : Op;
-def OP_SCALAR_QRDMULH_LNQ : Op;
-def OP_SCALAR_GET_LN : Op;
-def OP_SCALAR_SET_LN : Op;
+// These defs and classes are used internally to implement the SetTheory
+// expansion and should be ignored.
+foreach Index = 0-63 in
+  def sv##Index;
+class MaskExpand;
 
-class Inst <string n, string p, string t, Op o> {
+//===----------------------------------------------------------------------===//
+// Available operations
+//===----------------------------------------------------------------------===//
+
+// DAG arguments can either be operations (documented below) or variables.
+// Variables are prefixed with '$'. There are variables for each input argument,
+// with the name $pN, where N starts at zero. So the zero'th argument will be
+// $p0, the first $p1 etc.
+
+// op - Binary or unary operator, depending on the number of arguments. The
+//      operator itself is just treated as a raw string and is not checked.
+// example: (op "+", $p0, $p1) -> "__p0 + __p1".
+//          (op "-", $p0)      -> "-__p0"
+def op;
+// call - Invoke another intrinsic. The input types are type checked and
+//        disambiguated. If there is no intrinsic defined that takes
+//        the given types (or if there is a type ambiguity) an error is
+//        generated at tblgen time. The name of the intrinsic is the raw
+//        name as given to the Inst class (not mangled).
+// example: (call "vget_high", $p0) -> "vgetq_high_s16(__p0)"
+//            (assuming $p0 has type int16x8_t).
+def call;
+// cast - Perform a cast to a different type. This gets emitted as a static
+//        C-style cast. For a pure reinterpret cast (T x = *(T*)&y), use
+//        "bitcast".
+//
+//        The syntax is (cast MOD* VAL). The last argument is the value to
+//        cast, preceded by a sequence of type modifiers. The target type
+//        starts off as the type of VAL, and is modified by MOD in sequence.
+//        The available modifiers are:
+//          - $X  - Take the type of parameter/variable X. For example:
+//                  (cast $p0, $p1) would cast $p1 to the type of $p0.
+//          - "R" - The type of the return type.
+//          - A typedef string - A NEON or stdint.h type that is then parsed.
+//                               for example: (cast "uint32x4_t", $p0).
+//          - "U" - Make the type unsigned.
+//          - "S" - Make the type signed.
+//          - "H" - Halve the number of lanes in the type.
+//          - "D" - Double the number of lanes in the type.
+//          - "8" - Convert type to an equivalent vector of 8-bit signed
+//                  integers.
+// example: (cast "R", "U", $p0) -> "(uint32x4_t)__p0" (assuming the return
+//           value is of type "int32x4_t".
+//          (cast $p0, "D", "8", $p1) -> "(int8x16_t)__p1" (assuming __p0
+//           has type float64x1_t or any other vector type of 64 bits).
+//          (cast "int32_t", $p2) -> "(int32_t)__p2"
+def cast;
+// bitcast - Same as "cast", except a reinterpret-cast is produced:
+//             (bitcast "T", $p0) -> "*(T*)&__p0".
+//           The VAL argument is saved to a temprary so it can be used
+//           as an l-value.
+def bitcast;
+// dup - Take a scalar argument and create a vector by duplicating it into
+//       all lanes. The type of the vector is the base type of the intrinsic.
+// example: (dup $p1) -> "(uint32x2_t) {__p1, __p1}" (assuming the base type
+//          is uint32x2_t).
+def dup;
+// splat - Take a vector and a lane index, and return a vector of the same type
+//         containing repeated instances of the source vector at the lane index.
+// example: (splat $p0, $p1) ->
+//            "__builtin_shufflevector(__p0, __p0, __p1, __p1, __p1, __p1)"
+//          (assuming __p0 has four elements).
+def splat;
+// save_temp - Create a temporary (local) variable. The variable takes a name
+//             based on the zero'th parameter and can be referenced using
+//             using that name in subsequent DAGs in the same
+//             operation. The scope of a temp is the operation. If a variable
+//             with the given name already exists, an error will be given at
+//             tblgen time.
+// example: [(save_temp $var, (call "foo", $p0)),
+//           (op "+", $var, $p1)] ->
+//              "int32x2_t __var = foo(__p0); return __var + __p1;"
+def save_temp;
+// name_replace - Return the name of the current intrinsic with the first
+//                argument replaced by the second argument. Raises an error if
+//                the first argument does not exist in the intrinsic name.
+// example: (call (name_replace "_high_", "_"), $p0) (to call the non-high
+//            version of this intrinsic).
+def name_replace;
+// literal - Create a literal piece of code. The code is treated as a raw
+//           string, and must be given a type. The type is a stdint.h or
+//           NEON intrinsic type as given to (cast).
+// example: (literal "int32_t", "0")
+def literal;
+// shuffle - Create a vector shuffle. The syntax is (shuffle ARG0, ARG1, MASK).
+//           The MASK argument is a set of elements. The elements are generated
+//           from the two special defs "mask0" and "mask1". "mask0" expands to
+//           the lane indices in sequence for ARG0, and "mask1" expands to
+//           the lane indices in sequence for ARG1. They can be used as-is, e.g.
+//
+//             (shuffle $p0, $p1, mask0) -> $p0
+//             (shuffle $p0, $p1, mask1) -> $p1
+//
+//           or, more usefully, they can be manipulated using the SetTheory
+//           operators plus some extra operators defined in the NEON emitter.
+//           The operators are described below.
+// example: (shuffle $p0, $p1, (add (highhalf mask0), (highhalf mask1))) ->
+//            A concatenation of the high halves of the input vectors.
+def shuffle;
+
+// add, interleave, decimate: These set operators are vanilla SetTheory
+// operators and take their normal definition.
+def add;
+def interleave;
+def decimate;
+// rotl - Rotate set left by a number of elements.
+// example: (rotl mask0, 3) -> [3, 4, 5, 6, 0, 1, 2]
+def rotl;
+// rotl - Rotate set right by a number of elements.
+// example: (rotr mask0, 3) -> [4, 5, 6, 0, 1, 2, 3]
+def rotr;
+// highhalf - Take only the high half of the input.
+// example: (highhalf mask0) -> [4, 5, 6, 7] (assuming mask0 had 8 elements)
+def highhalf;
+// highhalf - Take only the low half of the input.
+// example: (lowhalf mask0) -> [0, 1, 2, 3] (assuming mask0 had 8 elements)
+def lowhalf;
+// rev - Perform a variable-width reversal of the elements. The zero'th argument
+//       is a width in bits to reverse. The lanes this maps to is determined
+//       based on the element width of the underlying type.
+// example: (rev 32, mask0) -> [3, 2, 1, 0, 7, 6, 5, 4] (if 8-bit elements)
+// example: (rev 32, mask0) -> [1, 0, 3, 2]             (if 16-bit elements)
+def rev;
+// mask0 - The initial sequence of lanes for shuffle ARG0
+def mask0 : MaskExpand;
+// mask0 - The initial sequence of lanes for shuffle ARG1
+def mask1 : MaskExpand;
+
+def OP_NONE  : Operation;
+def OP_UNAVAILABLE : Operation {
+  let Unavailable = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+
+// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and
+// a sequence of typespecs.
+//
+// The name is the base name of the intrinsic, for example "vget_lane". This is
+// then mangled by the tblgen backend to add type information ("vget_lane_s16").
+//
+// A typespec is a sequence of uppercase characters (modifiers) followed by one
+// lowercase character. A typespec encodes a particular "base type" of the
+// intrinsic.
+//
+// An example typespec is "Qs" - quad-size short - uint16x8_t. The available
+// typespec codes are given below.
+//
+// The string given to an Inst class is a sequence of typespecs. The intrinsic
+// is instantiated for every typespec in the sequence. For example "sdQsQd".
+//
+// The prototype is a string that defines the return type of the intrinsic
+// and the type of each argument. The return type and every argument gets a
+// "modifier" that can change in some way the "base type" of the intrinsic.
+//
+// The modifier 'd' means "default" and does not modify the base type in any
+// way. The available modifiers are given below.
+//
+// Typespecs
+// ---------
+// c: char
+// s: short
+// i: int
+// l: long
+// k: 128-bit long
+// f: float
+// h: half-float
+// d: double
+//
+// Typespec modifiers
+// ------------------
+// S: scalar, only used for function mangling.
+// U: unsigned
+// Q: 128b
+// H: 128b without mangling 'q'
+// P: polynomial
+//
+// Prototype modifiers
+// -------------------
+// prototype: return (arg, arg, ...)
+//
+// v: void
+// t: best-fit integer (int/poly args)
+// x: signed integer   (int/float args)
+// u: unsigned integer (int/float args)
+// f: float (int args)
+// F: double (int args)
+// d: default
+// g: default, ignore 'Q' size modifier.
+// j: default, force 'Q' size modifier.
+// w: double width elements, same num elts
+// n: double width elements, half num elts
+// h: half width elements, double num elts
+// q: half width elements, quad num elts
+// e: half width elements, double num elts, unsigned
+// m: half width elements, same num elts
+// i: constant int
+// l: constant uint64
+// s: scalar of element type
+// z: scalar of half width element type, signed
+// r: scalar of double width element type, signed
+// a: scalar of element type (splat to vector type)
+// b: scalar of unsigned integer/long type (int/float args)
+// $: scalar of signed integer/long type (int/float args)
+// y: scalar of float
+// o: scalar of double
+// k: default elt width, double num elts
+// 2,3,4: array of default vectors
+// B,C,D: array of default elts, force 'Q' size modifier.
+// p: pointer type
+// c: const pointer type
+
+// Every intrinsic subclasses Inst.
+class Inst <string n, string p, string t, Operation o> {
   string Name = n;
   string Prototype = p;
   string Types = t;
   string ArchGuard = "";
 
-  Op Operand = o;
+  Operation Operation = o;
+  bit CartesianProductOfTypes = 0;
+  bit BigEndianSafe = 0;
   bit isShift = 0;
   bit isScalarShift = 0;
   bit isScalarNarrowShift = 0;
@@ -186,60 +304,193 @@
 // WOpInst:       Instruction with bit size only suffix (e.g., "8").
 // LOpInst:       Logical instruction with no bit size suffix.
 // NoTestOpInst:  Intrinsic that has no corresponding instruction.
-class SOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
-class IOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
-class WOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
-class LOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
-class NoTestOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
+class SOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class IOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class WOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class LOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class NoTestOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
 
-// prototype: return (arg, arg, ...)
-// v: void
-// t: best-fit integer (int/poly args)
-// x: signed integer   (int/float args)
-// u: unsigned integer (int/float args)
-// f: float (int args)
-// F: double (int args)
-// d: default
-// g: default, ignore 'Q' size modifier.
-// j: default, force 'Q' size modifier.
-// w: double width elements, same num elts
-// n: double width elements, half num elts
-// h: half width elements, double num elts
-// q: half width elements, quad num elts
-// e: half width elements, double num elts, unsigned
-// m: half width elements, same num elts
-// i: constant int
-// l: constant uint64
-// s: scalar of element type
-// z: scalar of half width element type, signed
-// r: scalar of double width element type, signed
-// a: scalar of element type (splat to vector type)
-// b: scalar of unsigned integer/long type (int/float args)
-// $: scalar of signed integer/long type (int/float args)
-// y: scalar of float
-// o: scalar of double
-// k: default elt width, double num elts
-// 2,3,4: array of default vectors
-// B,C,D: array of default elts, force 'Q' size modifier.
-// p: pointer type
-// c: const pointer type
+//===----------------------------------------------------------------------===//
+// Operations
+//===----------------------------------------------------------------------===//
 
-// sizes:
-// c: char
-// s: short
-// i: int
-// l: long
-// k: 128-bit long
-// f: float
-// h: half-float
-// d: double
+def OP_ADD      : Op<(op "+", $p0, $p1)>;
+def OP_ADDL     : Op<(op "+", (call "vmovl", $p0), (call "vmovl", $p1))>;
+def OP_ADDLHi   : Op<(op "+", (call "vmovl_high", $p0),
+                              (call "vmovl_high", $p1))>;
+def OP_ADDW     : Op<(op "+", $p0, (call "vmovl", $p1))>;
+def OP_ADDWHi   : Op<(op "+", $p0, (call "vmovl_high", $p1))>;
+def OP_SUB      : Op<(op "-", $p0, $p1)>;
+def OP_SUBL     : Op<(op "-", (call "vmovl", $p0), (call "vmovl", $p1))>;
+def OP_SUBLHi   : Op<(op "-", (call "vmovl_high", $p0),
+                              (call "vmovl_high", $p1))>;
+def OP_SUBW     : Op<(op "-", $p0, (call "vmovl", $p1))>;
+def OP_SUBWHi   : Op<(op "-", $p0, (call "vmovl_high", $p1))>;
+def OP_MUL      : Op<(op "*", $p0, $p1)>;
+def OP_MLA      : Op<(op "+", $p0, (op "*", $p1, $p2))>;
+def OP_MLAL     : Op<(op "+", $p0, (call "vmull", $p1, $p2))>;
+def OP_MULLHi   : Op<(call "vmull", (call "vget_high", $p0),
+                                    (call "vget_high", $p1))>;
+def OP_MULLHi_P64 : Op<(call "vmull",
+                         (cast "poly64_t", (call "vget_high", $p0)),
+                         (cast "poly64_t", (call "vget_high", $p1)))>;
+def OP_MULLHi_N : Op<(call "vmull_n", (call "vget_high", $p0), $p1)>;
+def OP_MLALHi   : Op<(call "vmlal", $p0, (call "vget_high", $p1),
+                                         (call "vget_high", $p2))>;
+def OP_MLALHi_N : Op<(call "vmlal_n", $p0, (call "vget_high", $p1), $p2)>;
+def OP_MLS      : Op<(op "-", $p0, (op "*", $p1, $p2))>;
+def OP_MLSL     : Op<(op "-", $p0, (call "vmull", $p1, $p2))>;
+def OP_MLSLHi   : Op<(call "vmlsl", $p0, (call "vget_high", $p1),
+                                         (call "vget_high", $p2))>;
+def OP_MLSLHi_N : Op<(call "vmlsl_n", $p0, (call "vget_high", $p1), $p2)>;
+def OP_MUL_N    : Op<(op "*", $p0, (dup $p1))>;
+def OP_MLA_N    : Op<(op "+", $p0, (op "*", $p1, (dup $p2)))>;
+def OP_MLS_N    : Op<(op "-", $p0, (op "*", $p1, (dup $p2)))>;
+def OP_FMLA_N   : Op<(call "vfma", $p0, $p1, (dup $p2))>;
+def OP_FMLS_N   : Op<(call "vfms", $p0, $p1, (dup $p2))>;
+def OP_MLAL_N   : Op<(op "+", $p0, (call "vmull", $p1, (dup $p2)))>;
+def OP_MLSL_N   : Op<(op "-", $p0, (call "vmull", $p1, (dup $p2)))>;
+def OP_MUL_LN   : Op<(op "*", $p0, (splat $p1, $p2))>;
+def OP_MULX_LN  : Op<(call "vmulx", $p0, (splat $p1, $p2))>;
+def OP_MULL_LN  : Op<(call "vmull", $p0, (splat $p1, $p2))>;
+def OP_MULLHi_LN: Op<(call "vmull", (call "vget_high", $p0), (splat $p1, $p2))>;
+def OP_MLA_LN   : Op<(op "+", $p0, (op "*", $p1, (splat $p2, $p3)))>;
+def OP_MLS_LN   : Op<(op "-", $p0, (op "*", $p1, (splat $p2, $p3)))>;
+def OP_MLAL_LN  : Op<(op "+", $p0, (call "vmull", $p1, (splat $p2, $p3)))>;
+def OP_MLALHi_LN: Op<(op "+", $p0, (call "vmull", (call "vget_high", $p1),
+                                                  (splat $p2, $p3)))>;
+def OP_MLSL_LN  : Op<(op "-", $p0, (call "vmull", $p1, (splat $p2, $p3)))>;
+def OP_MLSLHi_LN : Op<(op "-", $p0, (call "vmull", (call "vget_high", $p1),
+                                                   (splat $p2, $p3)))>;
+def OP_QDMULL_LN : Op<(call "vqdmull", $p0, (splat $p1, $p2))>;
+def OP_QDMULLHi_LN : Op<(call "vqdmull", (call "vget_high", $p0),
+                                         (splat $p1, $p2))>;
+def OP_QDMLAL_LN : Op<(call "vqdmlal", $p0, $p1, (splat $p2, $p3))>;
+def OP_QDMLALHi_LN : Op<(call "vqdmlal", $p0, (call "vget_high", $p1),
+                                              (splat $p2, $p3))>;
+def OP_QDMLSL_LN : Op<(call "vqdmlsl", $p0, $p1, (splat $p2, $p3))>;
+def OP_QDMLSLHi_LN : Op<(call "vqdmlsl", $p0, (call "vget_high", $p1),
+                                              (splat $p2, $p3))>;
+def OP_QDMULH_LN : Op<(call "vqdmulh", $p0, (splat $p1, $p2))>;
+def OP_QRDMULH_LN : Op<(call "vqrdmulh", $p0, (splat $p1, $p2))>;
+def OP_FMS_LN   : Op<(call "vfma_lane", $p0, $p1, (op "-", $p2), $p3)>;
+def OP_FMS_LNQ  : Op<(call "vfma_laneq", $p0, $p1, (op "-", $p2), $p3)>;
+def OP_TRN1     : Op<(shuffle $p0, $p1, (interleave (decimate mask0, 2),
+                                                    (decimate mask1, 2)))>;
+def OP_ZIP1     : Op<(shuffle $p0, $p1, (lowhalf (interleave mask0, mask1)))>;
+def OP_UZP1     : Op<(shuffle $p0, $p1, (add (decimate mask0, 2),
+                                             (decimate mask1, 2)))>;
+def OP_TRN2     : Op<(shuffle $p0, $p1, (interleave
+                                          (decimate (rotl mask0, 1), 2),
+                                          (decimate (rotl mask1, 1), 2)))>;
+def OP_ZIP2     : Op<(shuffle $p0, $p1, (highhalf (interleave mask0, mask1)))>;
+def OP_UZP2     : Op<(shuffle $p0, $p1, (add (decimate (rotl mask0, 1), 2),
+                                             (decimate (rotl mask1, 1), 2)))>;
+def OP_EQ       : Op<(cast "R", (op "==", $p0, $p1))>;
+def OP_GE       : Op<(cast "R", (op ">=", $p0, $p1))>;
+def OP_LE       : Op<(cast "R", (op "<=", $p0, $p1))>;
+def OP_GT       : Op<(cast "R", (op ">", $p0, $p1))>;
+def OP_LT       : Op<(cast "R", (op "<", $p0, $p1))>;
+def OP_NEG      : Op<(op "-", $p0)>;
+def OP_NOT      : Op<(op "~", $p0)>;
+def OP_AND      : Op<(op "&", $p0, $p1)>;
+def OP_OR       : Op<(op "|", $p0, $p1)>;
+def OP_XOR      : Op<(op "^", $p0, $p1)>;
+def OP_ANDN     : Op<(op "&", $p0, (op "~", $p1))>;
+def OP_ORN      : Op<(op "|", $p0, (op "~", $p1))>;
+def OP_CAST     : Op<(cast "R", $p0)>;
+def OP_HI       : Op<(shuffle $p0, $p0, (highhalf mask0))>;
+def OP_LO       : Op<(shuffle $p0, $p0, (lowhalf mask0))>;
+def OP_CONC     : Op<(shuffle $p0, $p1, (add mask0, mask1))>;
+def OP_DUP      : Op<(dup $p0)>;
+def OP_DUP_LN   : Op<(splat $p0, $p1)>;
+def OP_SEL      : Op<(cast "R", (op "|",
+                                    (op "&", $p0, (cast $p0, $p1)),
+                                    (op "&", (op "~", $p0), (cast $p0, $p2))))>;
+def OP_REV16    : Op<(shuffle $p0, $p0, (rev 16, mask0))>;
+def OP_REV32    : Op<(shuffle $p0, $p0, (rev 32, mask0))>;
+def OP_REV64    : Op<(shuffle $p0, $p0, (rev 64, mask0))>;
+def OP_XTN      : Op<(call "vcombine", $p0, (call "vmovn", $p1))>;
+def OP_SQXTUN   : Op<(call "vcombine", (cast $p0, "U", $p0),
+                                       (call "vqmovun", $p1))>;
+def OP_QXTN     : Op<(call "vcombine", $p0, (call "vqmovn", $p1))>;
+def OP_VCVT_NA_HI_F16 : Op<(call "vcombine", $p0, (call "vcvt_f16", $p1))>;
+def OP_VCVT_NA_HI_F32 : Op<(call "vcombine", $p0, (call "vcvt_f32_f64", $p1))>;
+def OP_VCVT_EX_HI_F32 : Op<(call "vcvt_f32_f16", (call "vget_high", $p0))>;
+def OP_VCVT_EX_HI_F64 : Op<(call "vcvt_f64_f32", (call "vget_high", $p0))>;
+def OP_VCVTX_HI : Op<(call "vcombine", $p0, (call "vcvtx_f32", $p1))>;
+def OP_REINT    : Op<(cast "R", $p0)>;
+def OP_ADDHNHi  : Op<(call "vcombine", $p0, (call "vaddhn", $p1, $p2))>;
+def OP_RADDHNHi : Op<(call "vcombine", $p0, (call "vraddhn", $p1, $p2))>;
+def OP_SUBHNHi  : Op<(call "vcombine", $p0, (call "vsubhn", $p1, $p2))>;
+def OP_RSUBHNHi : Op<(call "vcombine", $p0, (call "vrsubhn", $p1, $p2))>;
+def OP_ABDL     : Op<(cast "R", (call "vmovl", (cast $p0, "U",
+                                                     (call "vabd", $p0, $p1))))>;
+def OP_ABDLHi   : Op<(call "vabdl", (call "vget_high", $p0),
+                                    (call "vget_high", $p1))>;
+def OP_ABA      : Op<(op "+", $p0, (call "vabd", $p1, $p2))>;
+def OP_ABAL     : Op<(op "+", $p0, (call "vabdl", $p1, $p2))>;
+def OP_ABALHi   : Op<(call "vabal", $p0, (call "vget_high", $p1),
+                                       (call "vget_high", $p2))>;
+def OP_QDMULLHi : Op<(call "vqdmull", (call "vget_high", $p0),
+                                      (call "vget_high", $p1))>;
+def OP_QDMULLHi_N : Op<(call "vqdmull_n", (call "vget_high", $p0), $p1)>;
+def OP_QDMLALHi : Op<(call "vqdmlal", $p0, (call "vget_high", $p1),
+                                           (call "vget_high", $p2))>;
+def OP_QDMLALHi_N : Op<(call "vqdmlal_n", $p0, (call "vget_high", $p1), $p2)>;
+def OP_QDMLSLHi : Op<(call "vqdmlsl", $p0, (call "vget_high", $p1),
+                                           (call "vget_high", $p2))>;
+def OP_QDMLSLHi_N : Op<(call "vqdmlsl_n", $p0, (call "vget_high", $p1), $p2)>;
+def OP_DIV  : Op<(op "/", $p0, $p1)>;
+def OP_LONG_HI : Op<(cast "R", (call (name_replace "_high_", "_"),
+                                                (call "vget_high", $p0), $p1))>;
+def OP_NARROW_HI : Op<(cast "R", (call "vcombine",
+                                       (cast "R", "H", $p0),
+                                       (cast "R", "H",
+                                           (call (name_replace "_high_", "_"),
+                                                 $p1, $p2))))>;
+def OP_MOVL_HI  : LOp<[(save_temp $a1, (call "vget_high", $p0)),
+                       (cast "R",
+                            (call "vshll_n", $a1, (literal "int32_t", "0")))]>;
+def OP_COPY_LN : Op<(call "vset_lane", (call "vget_lane", $p2, $p3), $p0, $p1)>;
+def OP_SCALAR_MUL_LN : Op<(op "*", $p0, (call "vget_lane", $p1, $p2))>;
+def OP_SCALAR_MULX_LN : Op<(call "vmulx", $p0, (call "vget_lane", $p1, $p2))>;
+def OP_SCALAR_VMULX_LN : LOp<[(save_temp $x, (call "vget_lane", $p0,
+                                                    (literal "int32_t", "0"))),
+                              (save_temp $y, (call "vget_lane", $p1, $p2)),
+                              (save_temp $z, (call "vmulx", $x, $y)),
+                              (call "vset_lane", $z, $p0, $p2)]>;
+def OP_SCALAR_VMULX_LNQ : LOp<[(save_temp $x, (call "vget_lane", $p0,
+                                                     (literal "int32_t", "0"))),
+                               (save_temp $y, (call "vget_lane", $p1, $p2)),
+                               (save_temp $z, (call "vmulx", $x, $y)),
+                               (call "vset_lane", $z, $p0, (literal "int32_t",
+                                                                     "0"))]>;
+class ScalarMulOp<string opname> :
+  Op<(call opname, $p0, (call "vget_lane", $p1, $p2))>;
 
-// size modifiers:
-// S: scalar, only used for function mangling.
-// U: unsigned
-// Q: 128b
-// H: 128b without mangling 'q'
-// P: polynomial
+def OP_SCALAR_QDMULL_LN : ScalarMulOp<"vqdmull">;
+def OP_SCALAR_QDMULH_LN : ScalarMulOp<"vqdmulh">;
+def OP_SCALAR_QRDMULH_LN : ScalarMulOp<"vqrdmulh">;
+
+def OP_SCALAR_HALF_GET_LN : Op<(bitcast "float16_t",
+                                   (call "vget_lane",
+                                         (bitcast "int16x4_t", $p0), $p1))>;
+def OP_SCALAR_HALF_GET_LNQ : Op<(bitcast "float16_t",
+                                    (call "vget_lane",
+                                          (bitcast "int16x8_t", $p0), $p1))>;
+def OP_SCALAR_HALF_SET_LN : Op<(bitcast "float16x4_t",
+                                   (call "vset_lane",
+                                         (bitcast "int16_t", $p0),
+                                         (bitcast "int16x4_t", $p1), $p2))>;
+def OP_SCALAR_HALF_SET_LNQ : Op<(bitcast "float16x8_t",
+                                    (call "vset_lane",
+                                          (bitcast "int16_t", $p0),
+                                          (bitcast "int16x8_t", $p1), $p2))>;
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
 
 ////////////////////////////////////////////////////////////////////////////////
 // E.3.1 Addition
@@ -404,7 +655,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // E.3.18 Initialize a vector from bit pattern
-def VCREATE : NoTestOpInst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST>;
+def VCREATE : NoTestOpInst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST> {
+  let BigEndianSafe = 1;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // E.3.19 Set all lanes to same value
@@ -538,7 +791,11 @@
 // E.3.31 Vector reinterpret cast operations
 def VREINTERPRET
   : NoTestOpInst<"vreinterpret", "dd",
-         "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT>;
+         "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT> {
+  let CartesianProductOfTypes = 1;
+  let ArchGuard = "!defined(__aarch64__)";
+  let BigEndianSafe = 1;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Vector fused multiply-add operations
@@ -678,13 +935,13 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Converting vectors
-def VCVT_HIGH_F16 : SOpInst<"vcvt_high_f16", "qhj", "f", OP_VCVT_NA_HI>;
-def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI>;
-def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "mj", "d">;
-def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI>;
+def VCVT_HIGH_F16 : SOpInst<"vcvt_high_f16", "qhj", "f", OP_VCVT_NA_HI_F16>;
+def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI_F32>;
+def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "md", "Qd">;
+def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI_F32>;
 def VCVT_F64_F32 : SInst<"vcvt_f64_f32", "wd", "f">;
 def VCVT_F64 : SInst<"vcvt_f64", "Fd",  "lUlQlQUl">;
-def VCVT_HIGH_F64_F32 : SOpInst<"vcvt_high_f64", "wj", "f", OP_VCVT_EX_HI>;
+def VCVT_HIGH_F64_F32 : SOpInst<"vcvt_high_f64", "wj", "f", OP_VCVT_EX_HI_F64>;
 def VCVTX_F32_F64 : SInst<"vcvtx_f32", "fj",  "d">;
 def VCVTX_HIGH_F32_F64 : SOpInst<"vcvtx_high_f32", "qfj", "d", OP_VCVTX_HI>;
 def FRINTN : SInst<"vrndn", "dd", "fdQfQd">;
@@ -819,16 +1076,16 @@
 def COPY_LANE : IOpInst<"vcopy_lane", "ddidi",
                         "csilUcUsUiUlPcPsPlfd", OP_COPY_LN>;
 def COPYQ_LANE : IOpInst<"vcopy_lane", "ddigi",
-                        "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPYQ_LN>;
+                        "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>;
 def COPY_LANEQ : IOpInst<"vcopy_laneq", "ddiki",
-                     "csilPcPsPlUcUsUiUlfd", OP_COPY_LNQ>;
+                     "csilPcPsPlUcUsUiUlfd", OP_COPY_LN>;
 def COPYQ_LANEQ : IOpInst<"vcopy_laneq", "ddidi",
                      "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Set all lanes to same value
 def VDUP_LANE1: WOpInst<"vdup_lane", "dgi", "hdQhQdPlQPl", OP_DUP_LN>;
-def VDUP_LANE2: WOpInst<"vdup_laneq", "dki",
+def VDUP_LANE2: WOpInst<"vdup_laneq", "dji",
                   "csilUcUsUiUlPcPshfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
                         OP_DUP_LN>;
 def DUP_N   : WOpInst<"vdup_n", "ds", "dQdPlQPl", OP_DUP>;
@@ -839,7 +1096,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 //Initialize a vector from bit pattern
-def CREATE : NoTestOpInst<"vcreate", "dl", "dPl", OP_CAST>;
+def CREATE : NoTestOpInst<"vcreate", "dl", "dPl", OP_CAST> {
+  let BigEndianSafe = 1;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -999,14 +1258,13 @@
 // NeonEmitter implicitly takes the cartesian product of the type string with
 // itself during generation so, unlike all other intrinsics, this one should
 // include *all* types, not just additional ones.
-//
-// We also rely on NeonEmitter handling the 32-bit vreinterpret before the
-// 64-bit one so that the common casts don't get guarded as AArch64-only
-// (FIXME).
 def VVREINTERPRET
   : NoTestOpInst<"vreinterpret", "dd",
-       "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", OP_REINT>;
-
+       "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", OP_REINT> {
+  let CartesianProductOfTypes = 1;
+  let BigEndianSafe = 1;
+  let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)";
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Scalar Intrinsics
@@ -1261,11 +1519,11 @@
 
 // Scalar Floating Point  multiply (scalar, by element)
 def SCALAR_FMUL_LANE : IOpInst<"vmul_lane", "ssdi", "SfSd", OP_SCALAR_MUL_LN>;
-def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "ssji", "SfSd", OP_SCALAR_MUL_LNQ>;
+def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "ssji", "SfSd", OP_SCALAR_MUL_LN>;
 
 // Scalar Floating Point  multiply extended (scalar, by element)
 def SCALAR_FMULX_LANE : IOpInst<"vmulx_lane", "ssdi", "SfSd", OP_SCALAR_MULX_LN>;
-def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "ssji", "SfSd", OP_SCALAR_MULX_LNQ>;
+def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "ssji", "SfSd", OP_SCALAR_MULX_LN>;
 
 def SCALAR_VMUL_N : IInst<"vmul_n", "dds", "d">;
 
@@ -1293,7 +1551,7 @@
 
 // Signed Saturating Doubling Multiply Long (scalar by element)
 def SCALAR_SQDMULL_LANE : SOpInst<"vqdmull_lane", "rsdi", "SsSi", OP_SCALAR_QDMULL_LN>;
-def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "rsji", "SsSi", OP_SCALAR_QDMULL_LNQ>;
+def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "rsji", "SsSi", OP_SCALAR_QDMULL_LN>;
 
 // Signed Saturating Doubling Multiply-Add Long (scalar by element)
 def SCALAR_SQDMLAL_LANE : SInst<"vqdmlal_lane", "rrsdi", "SsSi">;
@@ -1305,15 +1563,18 @@
 
 // Scalar Integer Saturating Doubling Multiply Half High (scalar by element)
 def SCALAR_SQDMULH_LANE : SOpInst<"vqdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QDMULH_LN>;
-def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QDMULH_LNQ>;
+def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QDMULH_LN>;
 
 // Scalar Integer Saturating Rounding Doubling Multiply Half High
 def SCALAR_SQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QRDMULH_LN>;
-def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QRDMULH_LNQ>;
+def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QRDMULH_LN>;
 
 def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
 def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
 
-def SCALAR_GET_LANE : IOpInst<"vget_lane", "sdi", "hQh", OP_SCALAR_GET_LN>;
-def SCALAR_SET_LANE : IOpInst<"vset_lane", "dsdi", "hQh", OP_SCALAR_SET_LN>;
+// FIXME: Rename so it is obvious this only applies to halfs.
+def SCALAR_HALF_GET_LANE : IOpInst<"vget_lane", "sdi", "h", OP_SCALAR_HALF_GET_LN>;
+def SCALAR_HALF_SET_LANE : IOpInst<"vset_lane", "dsdi", "h", OP_SCALAR_HALF_SET_LN>;
+def SCALAR_HALF_GET_LANEQ : IOpInst<"vget_lane", "sdi", "Qh", OP_SCALAR_HALF_GET_LNQ>;
+def SCALAR_HALF_SET_LANEQ : IOpInst<"vset_lane", "dsdi", "Qh", OP_SCALAR_HALF_SET_LNQ>;
 }
diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h
index 90c7494..2502982 100644
--- a/include/clang/CodeGen/CodeGenABITypes.h
+++ b/include/clang/CodeGen/CodeGenABITypes.h
@@ -63,9 +63,9 @@
   const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,
                                              const FunctionProtoType *FTP);
   const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType,
-                                         llvm::ArrayRef<CanQualType> argTypes,
-                                         FunctionType::ExtInfo info,
-                                         RequiredArgs args);
+                                                ArrayRef<CanQualType> argTypes,
+                                                FunctionType::ExtInfo info,
+                                                RequiredArgs args);
 
 private:
   /// Default CodeGenOptions object used to initialize the
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index cda7863..4b7236b 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -27,12 +27,14 @@
   class LangOptions;
   class CodeGenOptions;
   class TargetOptions;
+  class Decl;
 
   class CodeGenerator : public ASTConsumer {
     virtual void anchor();
   public:
     virtual llvm::Module* GetModule() = 0;
     virtual llvm::Module* ReleaseModule() = 0;
+    virtual const Decl *GetDeclForMangledName(llvm::StringRef MangledName) = 0;
   };
 
   /// CreateLLVMCodeGen - Create a CodeGenerator instance.
diff --git a/include/clang/Config/config.h b/include/clang/Config/config.h
index 51ef9f9..d469a0e 100644
--- a/include/clang/Config/config.h
+++ b/include/clang/Config/config.h
@@ -22,4 +22,12 @@
 /* Directory where gcc is installed. */
 #define GCC_INSTALL_PREFIX ""
 
+/* Define if we have libxml2 */
+/* #undef CLANG_HAVE_LIBXML */
+
+#define PACKAGE_STRING "LLVM 3.5.0svn"
+
+/* The LLVM product name and version */
+#define BACKEND_PACKAGE_STRING PACKAGE_STRING
+
 #endif
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index c18c4cc..7629ef9 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -1,3 +1,10 @@
+/* This generated file is for internal use. Do not include it from headers. */
+
+#ifdef CONFIG_H
+#error config.h can only be included once
+#else
+#define CONFIG_H
+
 /* Bug report URL. */
 #define BUG_REPORT_URL "${BUG_REPORT_URL}"
 
@@ -12,3 +19,11 @@
 
 /* Directory where gcc is installed. */
 #define GCC_INSTALL_PREFIX "${GCC_INSTALL_PREFIX}"
+
+/* Define if we have libxml2 */
+#cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML}
+
+/* The LLVM product name and version */
+#define BACKEND_PACKAGE_STRING "${BACKEND_PACKAGE_STRING}"
+
+#endif
diff --git a/include/clang/Config/config.h.in b/include/clang/Config/config.h.in
index 8ff9417..1530fef 100644
--- a/include/clang/Config/config.h.in
+++ b/include/clang/Config/config.h.in
@@ -1,6 +1,8 @@
-/* include/clang/Config/config.h.in. */
+/* This generated file is for internal use. Do not include it from headers. */
 
-#ifndef CONFIG_H
+#ifdef CONFIG_H
+#error config.h can only be included once
+#else
 #define CONFIG_H
 
 /* Bug report URL. */
@@ -21,4 +23,12 @@
 /* Directory where gcc is installed. */
 #undef GCC_INSTALL_PREFIX
 
+/* Define if we have libxml2 */
+#undef CLANG_HAVE_LIBXML
+
+#undef PACKAGE_STRING
+
+/* The LLVM product name and version */
+#define BACKEND_PACKAGE_STRING PACKAGE_STRING
+
 #endif
diff --git a/include/clang/Driver/CC1AsOptions.h b/include/clang/Driver/CC1AsOptions.h
deleted file mode 100644
index 345f50a..0000000
--- a/include/clang/Driver/CC1AsOptions.h
+++ /dev/null
@@ -1,37 +0,0 @@
-//===--- CC1AsOptions.h - Clang Assembler Options Table ---------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_DRIVER_CC1ASOPTIONS_H
-#define CLANG_DRIVER_CC1ASOPTIONS_H
-
-namespace llvm {
-namespace opt {
-  class OptTable;
-}
-}
-
-namespace clang {
-namespace driver {
-
-namespace cc1asoptions {
-  enum ID {
-    OPT_INVALID = 0, // This is not an option ID.
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
-               HELPTEXT, METAVAR) OPT_##ID,
-#include "clang/Driver/CC1AsOptions.inc"
-    LastOption
-#undef OPTION
-  };
-}
-
-llvm::opt::OptTable *createCC1AsOptTable();
-}
-}
-
-#endif
diff --git a/include/clang/Driver/CC1AsOptions.td b/include/clang/Driver/CC1AsOptions.td
deleted file mode 100644
index 34d6084..0000000
--- a/include/clang/Driver/CC1AsOptions.td
+++ /dev/null
@@ -1,105 +0,0 @@
-//===--- CC1AsOptions.td - Options for clang -cc1as -----------------------===//
-//
-//                     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 options accepted by clang -cc1as.
-//
-//===----------------------------------------------------------------------===//
-
-// Include the common option parsing interfaces.
-include "llvm/Option/OptParser.td"
-
-//===----------------------------------------------------------------------===//
-// Target Options
-//===----------------------------------------------------------------------===//
-
-def triple : Separate<["-"], "triple">,
-  HelpText<"Specify target triple (e.g. x86_64-pc-linux-gnu)">;
-def target_cpu : Separate<["-"], "target-cpu">,
-  HelpText<"Target a specific cpu type">;
-def target_feature : Separate<["-"], "target-feature">,
-  HelpText<"Target specific attributes">;
-
-//===----------------------------------------------------------------------===//
-// Language Options
-//===----------------------------------------------------------------------===//
-
-def I : JoinedOrSeparate<["-"], "I">, MetaVarName<"<directory>">,
-  HelpText<"Add directory to include search path">;
-def n : Flag<["-"], "n">,
-  HelpText<"Don't automatically start assembly file with a text section">;
-def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
-  HelpText<"Save temporary labels in the symbol table. "
-           "Note this may change .s semantics, it should almost never be used "
-           "on compiler generated code!">;
-def main_file_name : Separate<["-"], "main-file-name">,
-  HelpText<"Main file name to use for debug info">;
-
-//===----------------------------------------------------------------------===//
-// Frontend Options
-//===----------------------------------------------------------------------===//
-
-def o : Separate<["-"], "o">, MetaVarName<"<path>">,
-  HelpText<"Specify output file">;
-
-def filetype : Separate<["-"], "filetype">,
-    HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
-
-def help : Flag<["-", "--"], "help">,
-  HelpText<"Print this help text">;
-
-def version : Flag<["-", "--"], "version">,
-  HelpText<"Print the assembler version">;
-def v : Flag<["-"], "v">, Alias<version>;
-
-// Generic forwarding to LLVM options. This should only be used for debugging
-// and experimental features.
-def mllvm : Separate<["-"], "mllvm">,
-  HelpText<"Additional arguments to forward to LLVM's option processing">;
-
-//===----------------------------------------------------------------------===//
-// Transliterate Options
-//===----------------------------------------------------------------------===//
-
-def output_asm_variant : Separate<["-"], "output-asm-variant">,
-    HelpText<"Select the asm variant index to use for output">;
-def show_encoding : Flag<["-"], "show-encoding">,
-    HelpText<"Show instruction encoding information in transliterate mode">;
-def show_inst : Flag<["-"], "show-inst">,
-    HelpText<"Show internal instruction representation in transliterate mode">;
-
-//===----------------------------------------------------------------------===//
-// Assemble Options
-//===----------------------------------------------------------------------===//
-
-def mrelax_all : Flag<["-"], "mrelax-all">,
-    HelpText<"Relax all fixups (for performance testing)">;
-
-def mno_exec_stack : Flag<["-"], "mnoexecstack">,
-    HelpText<"Mark the file as not needing an executable stack">;
-
-def compress_debug_sections : Flag<["-"], "compress-debug-sections">,
-    HelpText<"Compress DWARF debug sections using zlib">;
-
-def g : Flag<["-"], "g">, HelpText<"Generate source level debug information">;
-
-def gdwarf_2 : Flag<["-"], "gdwarf-2">,
-  HelpText<"Generate source level debug information with dwarf version 2">;
-def gdwarf_3 : Flag<["-"], "gdwarf-3">,
-  HelpText<"Generate source level debug information with dwarf version 3">;
-def gdwarf_4 : Flag<["-"], "gdwarf-4">,
-  HelpText<"Generate source level debug information with dwarf version 4">;
-
-def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
-  HelpText<"The compilation directory to embed in the debug info.">;
-
-def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
-  HelpText<"The string to embed in the Dwarf debug flags record.">;
-
-def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
-  HelpText<"The string to embed in the Dwarf debug AT_producer record.">;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index b33198d..d25560c 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This file defines the options accepted by clang -cc1.
+//  This file defines the options accepted by clang -cc1 and clang -cc1as.
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,19 +17,24 @@
 // Target Options
 //===----------------------------------------------------------------------===//
 
-def target_abi : Separate<["-"], "target-abi">,
-  HelpText<"Target a particular ABI type">;
+let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
+
 def target_cpu : Separate<["-"], "target-cpu">,
   HelpText<"Target a specific cpu type">;
-def mfpmath : Separate<["-"], "mfpmath">,
-  HelpText<"Which unit to use for fp math">;
 def target_feature : Separate<["-"], "target-feature">,
   HelpText<"Target specific attributes">;
-def target_linker_version : Separate<["-"], "target-linker-version">,
-  HelpText<"Target linker version">;
 def triple : Separate<["-"], "triple">,
   HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
+
+}
+
+def target_abi : Separate<["-"], "target-abi">,
+  HelpText<"Target a particular ABI type">;
+def target_linker_version : Separate<["-"], "target-linker-version">,
+  HelpText<"Target linker version">;
 def triple_EQ : Joined<["-"], "triple=">, Alias<triple>;
+def mfpmath : Separate<["-"], "mfpmath">,
+  HelpText<"Which unit to use for fp math">;
 
 //===----------------------------------------------------------------------===//
 // Analyzer Options
@@ -122,16 +127,29 @@
 // CodeGen Options
 //===----------------------------------------------------------------------===//
 
+let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
+
+def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
+  HelpText<"The compilation directory to embed in the debug info.">;
+def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
+  HelpText<"The string to embed in the Dwarf debug flags record.">;
+def mno_exec_stack : Flag<["-"], "mnoexecstack">,
+  HelpText<"Mark the file as not needing an executable stack">;
+def compress_debug_sections : Flag<["-"], "compress-debug-sections">,
+    HelpText<"Compress DWARF debug sections using zlib">;
+def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
+  HelpText<"Save temporary labels in the symbol table. "
+           "Note this may change .s semantics and shouldn't generally be used "
+           "on compiler-generated code.">;
+
+}
+
 def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
   HelpText<"Don't run LLVM optimization passes">;
 def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">,
   HelpText<"Don't run the LLVM IR verifier pass">;
 def disable_red_zone : Flag<["-"], "disable-red-zone">,
   HelpText<"Do not emit code that uses the red zone.">;
-def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
-  HelpText<"The compilation directory to embed in the debug info.">;
-def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
-  HelpText<"The string to embed in the Dwarf debug flags record.">;
 def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
   HelpText<"Turn on column location information.">;
 def split_dwarf : Flag<["-"], "split-dwarf">,
@@ -188,10 +206,6 @@
   HelpText<"The float ABI to use">;
 def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">,
   HelpText<"Limit float precision to the given value">;
-def mno_exec_stack : Flag<["-"], "mnoexecstack">,
-  HelpText<"Mark the file as not needing an executable stack">;
-def compress_debug_sections : Flag<["-"], "compress-debug-sections">,
-    HelpText<"Compress DWARF debug sections using zlib">;
 def split_stacks : Flag<["-"], "split-stacks">,
   HelpText<"Try to use a split stack if possible.">;
 def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">,
@@ -200,8 +214,6 @@
   HelpText<"Additional arguments to forward to LLVM backend (during code gen)">;
 def mregparm : Separate<["-"], "mregparm">,
   HelpText<"Limit the number of registers available for integer arguments">;
-def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
-  HelpText<"(integrated-as) Save temporary labels">;
 def mrelocation_model : Separate<["-"], "mrelocation-model">,
   HelpText<"The relocation model to use">;
 def munwind_tables : Flag<["-"], "munwind-tables">,
@@ -230,7 +242,7 @@
 def header_include_file : Separate<["-"], "header-include-file">,
   HelpText<"Filename (or -) to write header include output to">;
 def show_includes : Flag<["--"], "show-includes">,
-  HelpText<"Print cl.exe style /showIncludes to stderr">;
+  HelpText<"Print cl.exe style /showIncludes to stdout">;
 
 //===----------------------------------------------------------------------===//
 // Diagnostic Options
@@ -272,6 +284,7 @@
 // This isn't normally used, it is just here so we can parse a
 // CompilerInvocation out of a driver-derived argument vector.
 def cc1 : Flag<["-"], "cc1">;
+def cc1as : Flag<["-"], "cc1as">;
 
 def ast_merge : Separate<["-"], "ast-merge">,
   MetaVarName<"<ast file>">,
@@ -303,8 +316,6 @@
     HelpText<"Pass <arg> to plugin <name>">;
 def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"<name>">,
   HelpText<"Use the named plugin action in addition to the default action">;
-def version : Flag<["-"], "version">,
-  HelpText<"Print the compiler version">;
 def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
   MetaVarName<"<dump_filter>">,
   HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
@@ -401,12 +412,19 @@
 // Language Options
 //===----------------------------------------------------------------------===//
 
+let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
+
+def version : Flag<["-"], "version">,
+  HelpText<"Print the compiler version">;
+def main_file_name : Separate<["-"], "main-file-name">,
+  HelpText<"Main file name to use for debug info">;
+
+}
+
 def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">,
   HelpText<"Weakly link in the blocks runtime">;
 def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">,
   HelpText<"Use SjLj style exceptions">;
-def main_file_name : Separate<["-"], "main-file-name">,
-  HelpText<"Main file name to use for debug info">;
 def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
   HelpText<"File name to use for split dwarf debug info output">;
 def fno_wchar : Flag<["-"], "fno-wchar">,
@@ -484,6 +502,8 @@
   HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">;
 def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
   HelpText<"Control vtordisp placement on win32 targets">;
+def fno_rtti_data : Flag<["-"], "fno-rtti-data">,
+  HelpText<"Control emission of RTTI data">;
 
 //===----------------------------------------------------------------------===//
 // Header Search Options
@@ -558,3 +578,32 @@
   HelpText<"Generate code for CUDA device">;
 
 } // let Flags = [CC1Option]
+
+
+//===----------------------------------------------------------------------===//
+// cc1as-only Options
+//===----------------------------------------------------------------------===//
+
+let Flags = [CC1AsOption, NoDriverOption] in {
+
+// Language Options
+def n : Flag<["-"], "n">,
+  HelpText<"Don't automatically start assembly file with a text section">;
+
+// Frontend Options
+def filetype : Separate<["-"], "filetype">,
+    HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
+
+// Transliterate Options
+def output_asm_variant : Separate<["-"], "output-asm-variant">,
+    HelpText<"Select the asm variant index to use for output">;
+def show_encoding : Flag<["-"], "show-encoding">,
+    HelpText<"Show instruction encoding information in transliterate mode">;
+def show_inst : Flag<["-"], "show-inst">,
+    HelpText<"Show internal instruction representation in transliterate mode">;
+
+// Assemble Options
+def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
+  HelpText<"The string to embed in the Dwarf debug AT_producer record.">;
+
+} // let Flags = [CC1AsOption]
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index a4881e2..90e3aca 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -58,8 +58,8 @@
 def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">,
   MetaVarName<"<macro[=value]>">, Alias<D>;
 def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>;
-def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable RTTI">, Alias<frtti>;
-def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable RTTI">, Alias<fno_rtti>;
+def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable emission of RTTI data">;
+def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">;
 def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">,
   Alias<fwritable_strings>;
 def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">,
@@ -140,6 +140,9 @@
 
 def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>;
 
+def _SLASH_EH : CLJoined<"EH">, HelpText<"Exception handling model">;
+def _SLASH_EP : CLFlag<"EP">,
+  HelpText<"Disable linemarker output and preprocess to stdout">;
 def _SLASH_FA : CLFlag<"FA">,
   HelpText<"Output assembly code file during compilation">;
 def _SLASH_Fa : CLJoined<"Fa">,
@@ -152,6 +155,9 @@
 def _SLASH_Fe : CLJoined<"Fe">,
   HelpText<"Set output executable file or directory (ends in / or \\)">,
   MetaVarName<"<file or directory>">;
+def _SLASH_Fi : CLCompileJoined<"Fi">,
+  HelpText<"Set preprocess output file name">,
+  MetaVarName<"<file>">;
 def _SLASH_Fo : CLCompileJoined<"Fo">,
   HelpText<"Set output object file, or directory (ends in / or \\)">,
   MetaVarName<"<file or directory>">;
@@ -192,6 +198,8 @@
 def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
 def _SLASH_w : CLIgnoredJoined<"w">;
 def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
+def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">;
+def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">;
 def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
 def _SLASH_Zm : CLIgnoredJoined<"Zm">;
 
@@ -204,14 +212,11 @@
 def _SLASH_clr : CLJoined<"clr">;
 def _SLASH_d2Zi_PLUS : CLFlag<"d2Zi+">;
 def _SLASH_doc : CLJoined<"doc">;
-def _SLASH_EH : CLJoined<"EH">;
-def _SLASH_EP : CLFlag<"EP">;
 def _SLASH_FA_joined : CLJoined<"FA">;
 def _SLASH_favor : CLJoined<"favor">;
 def _SLASH_FC : CLFlag<"FC">;
 def _SLASH_F : CLFlag<"F">;
 def _SLASH_Fd : CLJoined<"Fd">;
-def _SLASH_Fi : CLJoined<"Fi">;
 def _SLASH_Fm : CLJoined<"Fm">;
 def _SLASH_fp : CLJoined<"fp">;
 def _SLASH_Fp : CLJoined<"Fp">;
diff --git a/include/clang/Driver/CMakeLists.txt b/include/clang/Driver/CMakeLists.txt
index 5961cac..a9d9880 100644
--- a/include/clang/Driver/CMakeLists.txt
+++ b/include/clang/Driver/CMakeLists.txt
@@ -1,7 +1,3 @@
 set(LLVM_TARGET_DEFINITIONS Options.td)
 tablegen(LLVM Options.inc -gen-opt-parser-defs)
 add_public_tablegen_target(ClangDriverOptions)
-
-set(LLVM_TARGET_DEFINITIONS CC1AsOptions.td)
-tablegen(LLVM CC1AsOptions.inc -gen-opt-parser-defs)
-add_public_tablegen_target(ClangCC1AsOptions)
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 3493e4f..c1c0f43 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -69,6 +69,9 @@
   /// Redirection for stdout, stderr, etc.
   const StringRef **Redirects;
 
+  /// Whether we're compiling for diagnostic purposes.
+  bool ForDiagnostics;
+
 public:
   Compilation(const Driver &D, const ToolChain &DefaultToolChain,
               llvm::opt::InputArgList *Args,
@@ -173,6 +176,9 @@
   /// so compilation can be reexecuted to generate additional diagnostic
   /// information (e.g., preprocessed source(s)).
   void initCompilationForDiagnostics();
+
+  /// Return true if we're compiling for diagnostics.
+  bool isForDiagnostics() { return ForDiagnostics; }
 };
 
 } // end namespace driver
diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile
index 77cf6ff..8309330 100644
--- a/include/clang/Driver/Makefile
+++ b/include/clang/Driver/Makefile
@@ -1,5 +1,5 @@
 CLANG_LEVEL := ../../..
-BUILT_SOURCES = Options.inc CC1AsOptions.inc
+BUILT_SOURCES = Options.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
@@ -8,7 +8,3 @@
 $(ObjDir)/Options.inc.tmp : Options.td CC1Options.td CLCompatOptions.td $(LLVM_TBLGEN) $(ObjDir)/.dir
 	$(Echo) "Building Clang Driver Option tables with tblgen"
 	$(Verb) $(LLVMTableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CC1AsOptions.inc.tmp : CC1AsOptions.td $(LLVM_TBLGEN) $(ObjDir)/.dir
-	$(Echo) "Building Clang CC1 Assembler Option tables with tblgen"
-	$(Verb) $(LLVMTableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
index 28948be..cee705d 100644
--- a/include/clang/Driver/Options.h
+++ b/include/clang/Driver/Options.h
@@ -30,7 +30,8 @@
   CoreOption = (1 << 8),
   CLOption = (1 << 9),
   CC1Option = (1 << 10),
-  NoDriverOption = (1 << 11)
+  CC1AsOption = (1 << 11),
+  NoDriverOption = (1 << 12)
 };
 
 enum ID {
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 0e251aa..c37d2d8 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -44,6 +44,9 @@
 // CC1Option - This option should be accepted by clang -cc1.
 def CC1Option : OptionFlag;
 
+// CC1AsOption - This option should be accepted by clang -cc1as.
+def CC1AsOption : OptionFlag;
+
 // NoDriverOption - This option should not be accepted by the driver.
 def NoDriverOption : OptionFlag;
 
@@ -216,7 +219,7 @@
 def H : Flag<["-"], "H">, Flags<[CC1Option]>,
     HelpText<"Show header includes and nesting depth">;
 def I_ : Flag<["-"], "I-">, Group<I_Group>;
-def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option]>,
+def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option,CC1AsOption]>,
     HelpText<"Add directory to include search path">;
 def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>;
 def MD : Flag<["-"], "MD">, Group<M_Group>,
@@ -257,6 +260,14 @@
 def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_Group>, Flags<[CC1Option]>,
   HelpText<"Report transformations performed by optimization passes whose "
            "name matches the given POSIX regular expression">;
+def Rpass_missed_EQ : Joined<["-"], "Rpass-missed=">, Group<R_Group>,
+  Flags<[CC1Option]>,
+  HelpText<"Report missed transformations by optimization passes whose "
+           "name matches the given POSIX regular expression">;
+def Rpass_analysis_EQ : Joined<["-"], "Rpass-analysis=">, Group<R_Group>,
+  Flags<[CC1Option]>,
+  HelpText<"Report transformation analysis from optimization passes whose "
+           "name matches the given POSIX regular expression">;
 def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
   HelpText<"Only run preprocess and compilation steps">;
 def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>;
@@ -334,6 +345,8 @@
   HelpText<"Filename (or -) to write dependency output to">;
 def dependency_dot : Separate<["-"], "dependency-dot">, Flags<[CC1Option]>,
   HelpText<"Filename to write DOT-formatted header dependencies to">;
+def module_dependency_dir : Separate<["-"], "module-dependency-dir">,
+  Flags<[CC1Option]>, HelpText<"Directory to dump module dependencies to">;
 def dumpmachine : Flag<["-"], "dumpmachine">;
 def dumpspecs : Flag<["-"], "dumpspecs">, Flags<[Unsupported]>;
 def dumpversion : Flag<["-"], "dumpversion">;
@@ -459,6 +472,8 @@
 def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_f_Group>;
 def : Flag<["-"], "fno-expensive-optimizations">, Group<clang_ignored_f_Group>;
 def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>;
+def : Flag<["-"], "fdefer-pop">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fno-defer-pop">, Group<clang_ignored_f_Group>;
 def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
 def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
 def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
@@ -549,6 +564,7 @@
 def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
 def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_f_Group>;
 def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
+def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
 def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Generate calls to instrument function entry and exit">;
 def : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>;
@@ -846,12 +862,11 @@
            "in bytes than a given value">, Flags<[HelpHidden]>;
 def Wlarge_by_value_copy_EQ : Joined<["-"], "Wlarge-by-value-copy=">, Flags<[CC1Option]>;
 
-// Just silence warnings about -Wlarger-than,  -Wframe-larger-than for now.
-def Wlarger_than : Separate<["-"], "Wlarger-than">, Group<clang_ignored_f_Group>;
-def Wlarger_than_EQ : Joined<["-"], "Wlarger-than=">, Alias<Wlarger_than>;
-def Wlarger_than_ : Joined<["-"], "Wlarger-than-">, Alias<Wlarger_than>;
-def Wframe_larger_than : Separate<["-"], "Wframe-larger-than">, Group<clang_ignored_f_Group>;
-def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Alias<Wframe_larger_than>;
+// These "special" warning flags are effectively processed as f_Group flags by the driver:
+// Just silence warnings about -Wlarger-than for now.
+def Wlarger_than_EQ : Joined<["-"], "Wlarger-than=">, Group<clang_ignored_f_Group>;
+def Wlarger_than_ : Joined<["-"], "Wlarger-than-">, Alias<Wlarger_than_EQ>;
+def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Group<f_Group>, Flags<[DriverOption]>;
 
 def : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>;
 def fthreadsafe_statics : Flag<["-"], "fthreadsafe-statics">, Group<f_Group>;
@@ -911,7 +926,7 @@
 def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
   Flags<[CC1Option]>;
 def g_Flag : Flag<["-"], "g">, Group<g_Group>,
-  HelpText<"Generate source level debug information">, Flags<[CC1Option]>;
+  HelpText<"Generate source-level debug information">, Flags<[CC1Option,CC1AsOption]>;
 def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<g_Group>,
   HelpText<"Emit debug line number tables only">, Flags<[CC1Option]>;
 def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>;
@@ -925,11 +940,11 @@
 def ggdb2 : Flag<["-"], "ggdb2">, Group<g_Group>;
 def ggdb3 : Flag<["-"], "ggdb3">, Group<g_Group>;
 def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>,
-  HelpText<"Generate source level debug information with dwarf version 2">, Flags<[CC1Option]>;
+  HelpText<"Generate source-level debug information with dwarf version 2">, Flags<[CC1Option,CC1AsOption]>;
 def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group<g_Group>,
-  HelpText<"Generate source level debug information with dwarf version 3">, Flags<[CC1Option]>;
+  HelpText<"Generate source-level debug information with dwarf version 3">, Flags<[CC1Option,CC1AsOption]>;
 def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>,
-  HelpText<"Generate source level debug information with dwarf version 4">, Flags<[CC1Option]>;
+  HelpText<"Generate source-level debug information with dwarf version 4">, Flags<[CC1Option,CC1AsOption]>;
 def gfull : Flag<["-"], "gfull">, Group<g_Group>;
 def gused : Flag<["-"], "gused">, Group<g_Group>;
 def gstabs : Joined<["-"], "gstabs">, Group<g_Group>, Flags<[Unsupported]>;
@@ -947,7 +962,7 @@
 def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>;
 def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
 def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
-def help : Flag<["-", "--"], "help">, Flags<[CC1Option]>,
+def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption]>,
   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">;
@@ -1026,7 +1041,7 @@
 def mkernel : Flag<["-"], "mkernel">, Group<m_Group>;
 def mlinker_version_EQ : Joined<["-"], "mlinker-version=">,
   Flags<[DriverOption]>;
-def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option, CoreOption]>,
+def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option,CC1AsOption,CoreOption]>,
   HelpText<"Additional arguments to forward to LLVM's option processing">;
 def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">, Group<m_Group>;
 def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>,
@@ -1098,6 +1113,10 @@
   HelpText<"Allow use of CRC instructions (ARM only)">;
 def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
   HelpText<"Disallow use of CRC instructions (ARM only)">;
+def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_arm_Features_Group>,
+  HelpText<"Generate an indirect jump to enable jumps further than 64M">;
+def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_arm_Features_Group>,
+  HelpText<"Restore the default behaviour of not generating long calls">;
 
 def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
   HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
@@ -1129,7 +1148,7 @@
 def mpascal_strings : Flag<["-"], "mpascal-strings">, Alias<fpascal_strings>;
 def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>;
 def mregparm_EQ : Joined<["-"], "mregparm=">, Group<m_Group>;
-def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option]>,
+def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option,CC1AsOption]>,
   HelpText<"(integrated-as) Relax all machine instructions">;
 def mrtd : Flag<["-"], "mrtd">, Group<m_Group>, Flags<[CC1Option]>,
   HelpText<"Make StdCall calling convention the default">;
@@ -1196,18 +1215,45 @@
 def mfp32 : Flag<["-"], "mfp32">, Group<m_Group>,
   HelpText<"Use 32-bit floating point registers (MIPS only)">;
 def mnan_EQ : Joined<["-"], "mnan=">, Group<m_Group>;
+def mips1 : Flag<["-"], "mips1">,
+  Alias<march_EQ>, AliasArgs<["mips1"]>,
+  HelpText<"Equivalent to -march=mips1">, Flags<[HelpHidden]>;
+def mips2 : Flag<["-"], "mips2">,
+  Alias<march_EQ>, AliasArgs<["mips2"]>,
+  HelpText<"Equivalent to -march=mips2">, Flags<[HelpHidden]>;
+def mips3 : Flag<["-"], "mips3">,
+  Alias<march_EQ>, AliasArgs<["mips3"]>,
+  HelpText<"Equivalent to -march=mips3">, Flags<[HelpHidden]>;
+def mips4 : Flag<["-"], "mips4">,
+  Alias<march_EQ>, AliasArgs<["mips4"]>,
+  HelpText<"Equivalent to -march=mips4">, Flags<[HelpHidden]>;
+def mips5 : Flag<["-"], "mips5">,
+  Alias<march_EQ>, AliasArgs<["mips5"]>,
+  HelpText<"Equivalent to -march=mips5">, Flags<[HelpHidden]>;
 def mips32 : Flag<["-"], "mips32">,
   Alias<march_EQ>, AliasArgs<["mips32"]>,
   HelpText<"Equivalent to -march=mips32">, Flags<[HelpHidden]>;
 def mips32r2 : Flag<["-"], "mips32r2">,
   Alias<march_EQ>, AliasArgs<["mips32r2"]>,
   HelpText<"Equivalent to -march=mips32r2">, Flags<[HelpHidden]>;
+def mips32r6 : Flag<["-"], "mips32r6">,
+  Alias<march_EQ>, AliasArgs<["mips32r6"]>,
+  HelpText<"Equivalent to -march=mips32r6">, Flags<[HelpHidden]>;
 def mips64 : Flag<["-"], "mips64">,
   Alias<march_EQ>, AliasArgs<["mips64"]>,
   HelpText<"Equivalent to -march=mips64">, Flags<[HelpHidden]>;
 def mips64r2 : Flag<["-"], "mips64r2">,
   Alias<march_EQ>, AliasArgs<["mips64r2"]>,
   HelpText<"Equivalent to -march=mips64r2">, Flags<[HelpHidden]>;
+def mips64r6 : Flag<["-"], "mips64r6">,
+  Alias<march_EQ>, AliasArgs<["mips64r6"]>,
+  HelpText<"Equivalent to -march=mips64r6">, Flags<[HelpHidden]>;
+def modd_spreg : Flag<["-"], "modd-spreg">, Group<m_Group>,
+  HelpText<"Enable odd single-precision floating point registers">,
+  Flags<[HelpHidden]>;
+def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_Group>,
+  HelpText<"Disable odd single-precision floating point registers">,
+  Flags<[HelpHidden]>;
 def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>;
 def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
 def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>;
@@ -1237,7 +1283,7 @@
   HelpText<"Disable standard #include directories for the C++ standard library">;
 def nostdlib : Flag<["-"], "nostdlib">;
 def object : Flag<["-"], "object">;
-def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option]>,
+def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>,
   HelpText<"Write output to <file>">, MetaVarName<"<file>">;
 def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">;
 def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>;
@@ -1528,7 +1574,7 @@
 
 defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_f_Group>;
 def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_f_Group>;
-def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<clang_ignored_f_Group>;
+def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
 
 defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_f_Group>;
 def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_f_Group>;
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index f3db2c1..c9a6c4b 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -158,6 +158,10 @@
   std::string GetFilePath(const char *Name) const;
   std::string GetProgramPath(const char *Name) const;
 
+  /// Returns the linker path, respecting the -fuse-ld= argument to determine
+  /// the linker suffix or name.
+  std::string GetLinkerPath() const;
+
   /// \brief Dispatch to the specific toolchain for verbose printing.
   ///
   /// This is used when handling the verbose option to print detailed,
diff --git a/include/clang/Driver/Util.h b/include/clang/Driver/Util.h
index b24b990..c671ca4 100644
--- a/include/clang/Driver/Util.h
+++ b/include/clang/Driver/Util.h
@@ -13,6 +13,10 @@
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/DenseMap.h"
 
+namespace llvm {
+  class Triple;
+}
+
 namespace clang {
 class DiagnosticsEngine;
 
@@ -26,6 +30,9 @@
   /// ActionList - Type used for lists of actions.
   typedef SmallVector<Action*, 3> ActionList;
 
+/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
+const char* getARMCPUForMArch(StringRef MArch, const llvm::Triple &Triple);
+
 } // end namespace driver
 } // end namespace clang
 
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 244a9c6..45cccaa 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -17,7 +17,7 @@
 
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Tooling/Refactoring.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 
 namespace clang {
 
@@ -27,6 +27,15 @@
 
 namespace format {
 
+enum class ParseError { Success = 0, Error, Unsuitable };
+class ParseErrorCategory final : public std::error_category {
+public:
+  const char *name() const LLVM_NOEXCEPT override;
+  std::string message(int EV) const override;
+};
+const std::error_category &getParseCategory();
+std::error_code make_error_code(ParseError e);
+
 /// \brief The \c FormatStyle is used to configure the formatting to follow
 /// specific guidelines.
 struct FormatStyle {
@@ -76,12 +85,22 @@
   /// \brief The penalty for breaking a function call after "call(".
   unsigned PenaltyBreakBeforeFirstCallParameter;
 
-  /// \brief Set whether & and * bind to the type as opposed to the variable.
-  bool PointerBindsToType;
+  /// \brief The & and * alignment style.
+  enum PointerAlignmentStyle {
+    /// Align pointer to the left.
+    PAS_Left,
+    /// Align pointer to the right.
+    PAS_Right,
+    /// Align pointer in the middle.
+    PAS_Middle
+  };
 
-  /// \brief If \c true, analyze the formatted file for the most common binding
-  /// and use \c PointerBindsToType only as fallback.
-  bool DerivePointerBinding;
+  /// Pointer and reference alignment style.
+  PointerAlignmentStyle PointerAlignment;
+
+  /// \brief If \c true, analyze the formatted file for the most common
+  /// alignment of & and *. \c PointerAlignment is then used only as fallback.
+  bool DerivePointerAlignment;
 
   /// \brief The extra indent or outdent of access modifiers, e.g. \c public:.
   int AccessModifierOffset;
@@ -107,6 +126,10 @@
   /// Switch statement body is always indented one level more than case labels.
   bool IndentCaseLabels;
 
+  /// \brief Indent if a function definition or declaration is wrapped after the
+  /// type.
+  bool IndentWrappedFunctionNames;
+
   /// \brief Different ways to indent namespace contents.
   enum NamespaceIndentationKind {
     /// Don't indent in namespaces.
@@ -274,10 +297,6 @@
   /// a zero-length name is assumed.
   bool Cpp11BracedListStyle;
 
-  /// \brief If \c true, indent when breaking function declarations which
-  /// are not also definitions after the type.
-  bool IndentFunctionDeclarationAfterType;
-
   /// \brief If \c true, spaces will be inserted after '(' and before ')'.
   bool SpacesInParentheses;
 
@@ -364,12 +383,11 @@
            ColumnLimit == R.ColumnLimit &&
            ConstructorInitializerAllOnOneLineOrOnePerLine ==
                R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
-           DerivePointerBinding == R.DerivePointerBinding &&
+           DerivePointerAlignment == R.DerivePointerAlignment &&
            ExperimentalAutoDetectBinPacking ==
                R.ExperimentalAutoDetectBinPacking &&
            IndentCaseLabels == R.IndentCaseLabels &&
-           IndentFunctionDeclarationAfterType ==
-               R.IndentFunctionDeclarationAfterType &&
+           IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
            IndentWidth == R.IndentWidth && Language == R.Language &&
            MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
            KeepEmptyLinesAtTheStartOfBlocks ==
@@ -382,7 +400,7 @@
            PenaltyBreakString == R.PenaltyBreakString &&
            PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
            PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
-           PointerBindsToType == R.PointerBindsToType &&
+           PointerAlignment == R.PointerAlignment &&
            SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
            Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
            Standard == R.Standard && TabWidth == R.TabWidth &&
@@ -444,7 +462,7 @@
 ///
 /// When \c BasedOnStyle is not present, options not present in the YAML
 /// document, are retained in \p Style.
-llvm::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
+std::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
 
 /// \brief Gets configuration in a YAML string.
 std::string configurationAsText(const FormatStyle &Style);
@@ -506,4 +524,9 @@
 } // end namespace format
 } // end namespace clang
 
+namespace std {
+template <>
+struct is_error_code_enum<clang::format::ParseError> : std::true_type {};
+}
+
 #endif // LLVM_CLANG_FORMAT_FORMAT_H
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 3d7d0f2..42dc69a 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -83,7 +83,7 @@
   };
 
 private:
-  IntrusiveRefCntPtr<LangOptions>         LangOpts;
+  std::shared_ptr<LangOptions>            LangOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
   IntrusiveRefCntPtr<FileManager>         FileMgr;
   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
@@ -91,7 +91,7 @@
   IntrusiveRefCntPtr<TargetInfo>          Target;
   IntrusiveRefCntPtr<Preprocessor>        PP;
   IntrusiveRefCntPtr<ASTContext>          Ctx;
-  IntrusiveRefCntPtr<TargetOptions>       TargetOpts;
+  std::shared_ptr<TargetOptions>          TargetOpts;
   IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
   IntrusiveRefCntPtr<ASTReader> Reader;
   bool HadModuleLoaderFatalFailure;
@@ -692,7 +692,7 @@
 
   /// \brief A mapping from a file name to the memory buffer that stores the
   /// remapped contents of that file.
-  typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile;
+  typedef std::pair<std::string, llvm::MemoryBuffer *> RemappedFile;
 
   /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation. 
   static ASTUnit *create(CompilerInvocation *CI,
diff --git a/include/clang/Frontend/ChainedIncludesSource.h b/include/clang/Frontend/ChainedIncludesSource.h
deleted file mode 100644
index 676e749..0000000
--- a/include/clang/Frontend/ChainedIncludesSource.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===- ChainedIncludesSource.h - Chained PCHs in Memory ---------*- 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 ChainedIncludesSource class, which converts headers
-//  to chained PCHs in memory, mainly used for testing.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATION_CHAINEDINCLUDESSOURCE_H
-#define LLVM_CLANG_SERIALIZATION_CHAINEDINCLUDESSOURCE_H
-
-#include "clang/Sema/ExternalSemaSource.h"
-#include <vector>
-
-namespace clang {
-  class CompilerInstance;
-
-class ChainedIncludesSource : public ExternalSemaSource {
-public:
-  virtual ~ChainedIncludesSource();
-
-  static IntrusiveRefCntPtr<ChainedIncludesSource> create(CompilerInstance &CI);
-
-  ExternalSemaSource &getFinalReader() const { return *FinalReader; }
-
-private:
-  std::vector<CompilerInstance *> CIs;
-  IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
-
-  
-protected:
-
-//===----------------------------------------------------------------------===//
-// ExternalASTSource interface.
-//===----------------------------------------------------------------------===//
-
-  Decl *GetExternalDecl(uint32_t ID) override;
-  Selector GetExternalSelector(uint32_t ID) override;
-  uint32_t GetNumExternalSelectors() override;
-  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
-  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
-  bool FindExternalVisibleDeclsByName(const DeclContext *DC,
-                                      DeclarationName Name) override;
-  ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
-                                bool (*isKindWeWant)(Decl::Kind),
-                                SmallVectorImpl<Decl*> &Result) override;
-  void CompleteType(TagDecl *Tag) override;
-  void CompleteType(ObjCInterfaceDecl *Class) override;
-  void StartedDeserializing() override;
-  void FinishedDeserializing() override;
-  void StartTranslationUnit(ASTConsumer *Consumer) override;
-  void PrintStats() override;
-
-  /// Return the amount of memory used by memory buffers, breaking down
-  /// by heap-backed versus mmap'ed memory.
-  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
-
-//===----------------------------------------------------------------------===//
-// ExternalSemaSource interface.
-//===----------------------------------------------------------------------===//
-
-  void InitializeSema(Sema &S) override;
-  void ForgetSema() override;
-  void ReadMethodPool(Selector Sel) override;
-  bool LookupUnqualified(LookupResult &R, Scope *S) override;
-};
-
-}
-
-#endif
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 8959185..1d92efe 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -140,7 +140,7 @@
 VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
 
 /// The kind of generated debug info.
-ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 2, NoDebugInfo)
+ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo)
 
 /// Dwarf version.
 VALUE_CODEGENOPT(DwarfVersion, 3, 0)
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 9c8de1b..3d532ce 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -53,6 +53,13 @@
   enum DebugInfoKind {
     NoDebugInfo,          /// Don't generate debug info.
 
+    LocTrackingOnly,      /// Emit location information but do not generate
+                          /// debug info in the output. This is useful in
+                          /// cases where the backend wants to track source
+                          /// locations for instructions without actually
+                          /// emitting debug info for them (e.g., when -Rpass
+                          /// is used).
+
     DebugLineTablesOnly,  /// Emit only debug info necessary for generating
                           /// line number tables (-gline-tables-only).
 
@@ -153,6 +160,21 @@
   /// -Rpass=regexp flag.
   std::shared_ptr<llvm::Regex> OptimizationRemarkPattern;
 
+  /// Regular expression to select optimizations for which we should enable
+  /// missed optimization remarks. Transformation passes whose name matches this
+  /// expression (and support this feature), will emit a diagnostic
+  /// whenever they tried but failed to perform a transformation. This is
+  /// enabled by the -Rpass-missed=regexp flag.
+  std::shared_ptr<llvm::Regex> OptimizationRemarkMissedPattern;
+
+  /// Regular expression to select optimizations for which we should enable
+  /// optimization analyses. Transformation passes whose name matches this
+  /// expression (and support this feature), will emit a diagnostic
+  /// whenever they want to explain why they decided to apply or not apply
+  /// a given transformation. This is enabled by the -Rpass-analysis=regexp
+  /// flag.
+  std::shared_ptr<llvm::Regex> OptimizationRemarkAnalysisPattern;
+
 public:
   // Define accessors/mutators for code generation options of enumeration type.
 #define CODEGENOPT(Name, Bits, Default)
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 97c140e..44e9102 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -105,9 +105,14 @@
   /// \brief The ASTReader, if one exists.
   IntrusiveRefCntPtr<ASTReader> ModuleManager;
 
+  /// \brief The module dependency collector for crashdumps
+  std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
+
   /// \brief The dependency file generator.
   std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator;
 
+  std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
+
   /// \brief The set of top-level modules that has already been loaded,
   /// along with the module map
   llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
@@ -355,7 +360,7 @@
   }
   
   void resetAndLeakFileManager() {
-    BuryPointer(FileMgr.getPtr());
+    BuryPointer(FileMgr.get());
     FileMgr.resetWithoutRelease();
   }
 
@@ -375,7 +380,7 @@
   }
   
   void resetAndLeakSourceManager() {
-    BuryPointer(SourceMgr.getPtr());
+    BuryPointer(SourceMgr.get());
     SourceMgr.resetWithoutRelease();
   }
 
@@ -395,7 +400,7 @@
   }
 
   void resetAndLeakPreprocessor() {
-    BuryPointer(PP.getPtr());
+    BuryPointer(PP.get());
     PP.resetWithoutRelease();
   }
 
@@ -414,7 +419,7 @@
   }
   
   void resetAndLeakASTContext() {
-    BuryPointer(Context.getPtr());
+    BuryPointer(Context.get());
     Context.resetWithoutRelease();
   }
 
@@ -464,6 +469,10 @@
   IntrusiveRefCntPtr<ASTReader> getModuleManager() const;
   void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader);
 
+  std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
+  void setModuleDepCollector(
+      std::shared_ptr<ModuleDependencyCollector> Collector);
+
   /// }
   /// @name Code Completion
   /// {
@@ -663,6 +672,8 @@
                    std::string *ResultPathName,
                    std::string *TempPathName);
 
+  llvm::raw_null_ostream *createNullOutputFile();
+
   /// }
   /// @name Initialization Utility Methods
   /// {
@@ -702,6 +713,10 @@
   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
 
   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
+
+  void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
+    DependencyCollectors.push_back(std::move(Listener));
+  }
 };
 
 } // end namespace clang
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index 3d7467c..f05ab80 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -52,12 +52,12 @@
 class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
   void operator=(const CompilerInvocationBase &) LLVM_DELETED_FUNCTION;
 
-protected:
+public:
   /// Options controlling the language variant.
-  IntrusiveRefCntPtr<LangOptions> LangOpts;
+  std::shared_ptr<LangOptions> LangOpts;
 
   /// Options controlling the target.
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
 
   /// Options controlling the diagnostic engine.
   IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;
@@ -68,18 +68,17 @@
   /// Options controlling the preprocessor (aside from \#include handling).
   IntrusiveRefCntPtr<PreprocessorOptions> PreprocessorOpts;
 
-public:
   CompilerInvocationBase();
   ~CompilerInvocationBase();
 
   CompilerInvocationBase(const CompilerInvocationBase &X);
   
-  LangOptions *getLangOpts() { return LangOpts.getPtr(); }
-  const LangOptions *getLangOpts() const { return LangOpts.getPtr(); }
+  LangOptions *getLangOpts() { return LangOpts.get(); }
+  const LangOptions *getLangOpts() const { return LangOpts.get(); }
 
-  TargetOptions &getTargetOpts() { return *TargetOpts.getPtr(); }
+  TargetOptions &getTargetOpts() { return *TargetOpts.get(); }
   const TargetOptions &getTargetOpts() const {
-    return *TargetOpts.getPtr();
+    return *TargetOpts.get();
   }
 
   DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
index d275249..5da1459 100644
--- a/include/clang/Frontend/DependencyOutputOptions.h
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -43,7 +43,10 @@
 
   /// \brief The file to write GraphViz-formatted header dependencies to.
   std::string DOTOutputFile;
-  
+
+  /// \brief The directory to copy module dependencies to when collecting them.
+  std::string ModuleDependencyOutputDir;
+
 public:
   DependencyOutputOptions() {
     IncludeSystemHeaders = 0;
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index 019eec5..ce1dc90 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -83,9 +83,7 @@
                                  DiagnosticsEngine::Level Level,
                                  ArrayRef<CharSourceRange> Ranges,
                                  const SourceManager &SM) = 0;
-  
-  virtual void emitBasicNote(StringRef Message) = 0;
-  
+
   virtual void emitCodeContext(SourceLocation Loc,
                                DiagnosticsEngine::Level Level,
                                SmallVectorImpl<CharSourceRange>& Ranges,
@@ -108,6 +106,7 @@
 
   
 private:
+  void emitBasicNote(StringRef Message);
   void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc,
                         DiagnosticsEngine::Level Level, const SourceManager &SM);
   void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
@@ -159,8 +158,6 @@
   
   virtual ~DiagnosticNoteRenderer();
 
-  void emitBasicNote(StringRef Message) override;
-
   void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
                            const SourceManager &SM) override;
 
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
index 1124d53..9680e1f 100644
--- a/include/clang/Frontend/LangStandard.h
+++ b/include/clang/Frontend/LangStandard.h
@@ -25,10 +25,11 @@
   CPlusPlus = (1 << 4),
   CPlusPlus11 = (1 << 5),
   CPlusPlus1y = (1 << 6),
-  Digraphs = (1 << 7),
-  GNUMode = (1 << 8),
-  HexFloat = (1 << 9),
-  ImplicitInt = (1 << 10)
+  CPlusPlus1z = (1 << 7),
+  Digraphs = (1 << 8),
+  GNUMode = (1 << 9),
+  HexFloat = (1 << 10),
+  ImplicitInt = (1 << 11)
 };
 
 }
@@ -69,12 +70,15 @@
   /// isCPlusPlus - Language is a C++ variant.
   bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
 
-  /// isCPlusPlus11 - Language is a C++0x variant.
+  /// isCPlusPlus11 - Language is a C++11 variant (or later).
   bool isCPlusPlus11() const { return Flags & frontend::CPlusPlus11; }
 
-  /// isCPlusPlus1y - Language is a C++1y variant.
+  /// isCPlusPlus1y - Language is a C++14 variant (or later).
   bool isCPlusPlus1y() const { return Flags & frontend::CPlusPlus1y; }
 
+  /// isCPlusPlus1z - Language is a C++17 variant (or later).
+  bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; }
+
   /// hasDigraphs - Language supports digraphs.
   bool hasDigraphs() const { return Flags & frontend::Digraphs; }
 
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index 7b2516b..da9a118 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -115,6 +115,15 @@
              LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs |
              GNUMode)
 
+LANGSTANDARD(cxx1z, "c++1z",
+             "Working draft for ISO C++ 2017",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z |
+             Digraphs)
+LANGSTANDARD(gnucxx1z, "gnu++1z",
+             "Working draft for ISO C++ 2017 with GNU extensions",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z |
+             Digraphs | GNUMode)
+
 // OpenCL
 LANGSTANDARD(opencl, "cl",
              "OpenCL 1.0",
diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h
index 4ef643e..0130319 100644
--- a/include/clang/Frontend/LogDiagnosticPrinter.h
+++ b/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -39,7 +39,10 @@
     /// The level of the diagnostic.
     DiagnosticsEngine::Level DiagnosticLevel;
   };
-  
+
+  void EmitDiagEntry(llvm::raw_ostream &OS,
+                     const LogDiagnosticPrinter::DiagEntry &DE);
+
   raw_ostream &OS;
   const LangOptions *LangOpts;
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
index 2aa9576..acebb90 100644
--- a/include/clang/Frontend/TextDiagnostic.h
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -63,18 +63,16 @@
   /// formatting of their diagnostic messages.
   ///
   /// \param OS Where the message is printed
-  /// \param Level Used to colorizing the message
+  /// \param IsSupplemental true if this is a continuation note diagnostic
   /// \param Message The text actually printed
   /// \param CurrentColumn The starting column of the first line, accounting
   ///                      for any prefix.
   /// \param Columns The number of columns to use in line-wrapping, 0 disables
   ///                all line-wrapping.
   /// \param ShowColors Enable colorizing of the message.
-  static void printDiagnosticMessage(raw_ostream &OS,
-                                     DiagnosticsEngine::Level Level,
-                                     StringRef Message,
-                                     unsigned CurrentColumn, unsigned Columns,
-                                     bool ShowColors);
+  static void printDiagnosticMessage(raw_ostream &OS, bool IsSupplemental,
+                                     StringRef Message, unsigned CurrentColumn,
+                                     unsigned Columns, bool ShowColors);
 
 protected:
   void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
@@ -97,8 +95,6 @@
     emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM);
   }
 
-  void emitBasicNote(StringRef Message) override;
-
   void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
                            const SourceManager &SM) override;
 
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 8fb536f..4c0a7b7 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -15,8 +15,10 @@
 #define LLVM_CLANG_FRONTEND_UTILS_H
 
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/VirtualFileSystem.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Option/OptSpecifier.h"
 
 namespace llvm {
@@ -37,6 +39,7 @@
 class DependencyOutputOptions;
 class DiagnosticsEngine;
 class DiagnosticOptions;
+class ExternalSemaSource;
 class FileManager;
 class HeaderSearch;
 class HeaderSearchOptions;
@@ -60,13 +63,45 @@
 /// environment ready to process a single file.
 void InitializePreprocessor(Preprocessor &PP,
                             const PreprocessorOptions &PPOpts,
-                            const HeaderSearchOptions &HSOpts,
                             const FrontendOptions &FEOpts);
 
 /// DoPrintPreprocessedInput - Implement -E mode.
 void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
                               const PreprocessorOutputOptions &Opts);
 
+/// An interface for collecting the dependencies of a compilation. Users should
+/// use \c attachToPreprocessor and \c attachToASTReader to get all of the
+/// dependencies.
+// FIXME: Migrate DependencyFileGen, DependencyGraphGen, ModuleDepCollectory to
+// use this interface.
+class DependencyCollector {
+public:
+  void attachToPreprocessor(Preprocessor &PP);
+  void attachToASTReader(ASTReader &R);
+  llvm::ArrayRef<std::string> getDependencies() const { return Dependencies; }
+
+  /// Called when a new file is seen. Return true if \p Filename should be added
+  /// to the list of dependencies.
+  ///
+  /// The default implementation ignores <built-in> and system files.
+  virtual bool sawDependency(StringRef Filename, bool FromModule,
+                             bool IsSystem, bool IsModuleFile, bool IsMissing);
+  /// Called when the end of the main file is reached.
+  virtual void finishedMainFile() { }
+  /// Return true if system files should be passed to sawDependency().
+  virtual bool needSystemDependencies() { return false; }
+  virtual ~DependencyCollector();
+
+public: // implementation detail
+  /// Add a dependency \p Filename if it has not been seen before and
+  /// sawDependency() returns true.
+  void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem,
+                          bool IsModuleFile, bool IsMissing);
+private:
+  llvm::StringSet<> Seen;
+  std::vector<std::string> Dependencies;
+};
+
 /// Builds a depdenency file when attached to a Preprocessor (for includes) and
 /// ASTReader (for module imports), and writes it out at the end of processing
 /// a source file.  Users should attach to the ast reader whenever a module is
@@ -80,6 +115,30 @@
   void AttachToASTReader(ASTReader &R);
 };
 
+/// Collects the dependencies for imported modules into a directory.  Users
+/// should attach to the AST reader whenever a module is loaded.
+class ModuleDependencyCollector {
+  std::string DestDir;
+  bool HasErrors;
+  llvm::StringSet<> Seen;
+  vfs::YAMLVFSWriter VFSWriter;
+
+public:
+  StringRef getDest() { return DestDir; }
+  bool insertSeen(StringRef Filename) { return Seen.insert(Filename); }
+  void setHasErrors() { HasErrors = true; }
+  void addFileMapping(StringRef VPath, StringRef RPath) {
+    VFSWriter.addFileMapping(VPath, RPath);
+  }
+
+  void attachToASTReader(ASTReader &R);
+  void writeFileMap();
+  bool hasErrors() { return HasErrors; }
+  ModuleDependencyCollector(std::string DestDir)
+      : DestDir(DestDir), HasErrors(false) {}
+  ~ModuleDependencyCollector() { writeFileMap(); }
+};
+
 /// AttachDependencyGraphGen - Create a dependency graph generator, and attach
 /// it to the given preprocessor.
   void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile,
@@ -104,6 +163,12 @@
 /// a seekable stream.
 void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS);
 
+/// The ChainedIncludesSource class converts headers to chained PCHs in
+/// memory, mainly for testing.
+IntrusiveRefCntPtr<ExternalSemaSource>
+createChainedIncludesSource(CompilerInstance &CI,
+                            IntrusiveRefCntPtr<ExternalSemaSource> &Reader);
+
 /// createInvocationFromCommandLine - Construct a compiler invocation object for
 /// a command line argument vector.
 ///
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index 084eb66..9273fac 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -71,7 +71,10 @@
 /// \endcode
 ///
 /// The path can be absolute or relative and the same search paths will be used
-/// as for #include directives.
+/// as for #include directives.  The line number in an external file may be
+/// substituted with '*' meaning that any line number will match (useful where
+/// the included file is, for example, a system header where the actual line
+/// number may change and is not critical).
 ///
 /// The simple syntax above allows each specification to match exactly one
 /// error.  You can use the extended syntax to customize this. The extended
@@ -143,7 +146,7 @@
   class Directive {
   public:
     static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
-                             SourceLocation DiagnosticLoc,
+                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
                              StringRef Text, unsigned Min, unsigned Max);
   public:
     /// Constant representing n or more matches.
@@ -153,6 +156,7 @@
     SourceLocation DiagnosticLoc;
     const std::string Text;
     unsigned Min, Max;
+    bool MatchAnyLine;
 
     virtual ~Directive() { }
 
@@ -165,9 +169,9 @@
 
   protected:
     Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-              StringRef Text, unsigned Min, unsigned Max)
+              bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
       : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
-        Text(Text), Min(Min), Max(Max) {
+        Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
     assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
     assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
     }
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 2eb7751..b7fcc5d 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -63,7 +63,7 @@
   bool isLongLong;
   bool isFloat;       // 1.0f
   bool isImaginary;   // 1.0i
-  bool isMicrosoftInteger;  // Microsoft suffix extension i8, i16, i32, or i64.
+  uint8_t MicrosoftInteger;  // Microsoft suffix extension i8, i16, i32, or i64.
 
   bool isIntegerLiteral() const {
     return !saw_period && !saw_exponent;
@@ -196,16 +196,16 @@
   unsigned UDSuffixToken;
   unsigned UDSuffixOffset;
 public:
-  StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+  StringLiteralParser(ArrayRef<Token> StringToks,
                       Preprocessor &PP, bool Complain = true);
-  StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+  StringLiteralParser(ArrayRef<Token> StringToks,
                       const SourceManager &sm, const LangOptions &features,
                       const TargetInfo &target,
                       DiagnosticsEngine *diags = nullptr)
     : SM(sm), Features(features), Target(target), Diags(diags),
       MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
       ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
-    init(StringToks, NumStringToks);
+    init(StringToks);
   }
     
 
@@ -249,7 +249,7 @@
   }
 
 private:
-  void init(const Token *StringToks, unsigned NumStringToks);
+  void init(ArrayRef<Token> StringToks);
   bool CopyStringFragment(const Token &Tok, const char *TokBegin,
                           StringRef Fragment);
   void DiagnoseLexingError(SourceLocation Loc);
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 974ab55..7f1ea34 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -214,8 +214,7 @@
 
   /// \brief Callback invoked when a \#pragma gcc dianostic directive is read.
   virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
-                                diag::Mapping mapping, StringRef Str) {
-  }
+                                diag::Severity mapping, StringRef Str) {}
 
   /// \brief Called when an OpenCL extension is either disabled or
   /// enabled with a pragma.
@@ -411,7 +410,7 @@
   }
 
   void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
-                        diag::Mapping mapping, StringRef Str) override {
+                        diag::Severity mapping, StringRef Str) override {
     First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
     Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
   }
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index eba2a13..135c87f 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -97,14 +97,13 @@
   /// the system (the first part of each pair) and gives them the
   /// contents of other files on the system (the second part of each
   /// pair).
-  std::vector<std::pair<std::string, std::string> >  RemappedFiles;
+  std::vector<std::pair<std::string, std::string>> RemappedFiles;
 
   /// \brief The set of file-to-buffer remappings, which take existing files
   /// on the system (the first part of each pair) and gives them the contents
   /// of the specified memory buffer (the second part of each pair).
-  std::vector<std::pair<std::string, const llvm::MemoryBuffer *> > 
-    RemappedFileBuffers;
-  
+  std::vector<std::pair<std::string, llvm::MemoryBuffer *>> RemappedFileBuffers;
+
   /// \brief Whether the compiler instance should retain (i.e., not free)
   /// the buffers associated with remapped files.
   ///
@@ -140,40 +139,6 @@
   /// build it again.
   IntrusiveRefCntPtr<FailedModulesSet> FailedModules;
 
-  typedef std::vector<std::pair<std::string, std::string> >::iterator
-    remapped_file_iterator;
-  typedef std::vector<std::pair<std::string, std::string> >::const_iterator
-    const_remapped_file_iterator;
-  remapped_file_iterator remapped_file_begin() { 
-    return RemappedFiles.begin();
-  }
-  const_remapped_file_iterator remapped_file_begin() const {
-    return RemappedFiles.begin();
-  }
-  remapped_file_iterator remapped_file_end() { 
-    return RemappedFiles.end();
-  }
-  const_remapped_file_iterator remapped_file_end() const { 
-    return RemappedFiles.end();
-  }
-
-  typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >::
-                                  iterator remapped_file_buffer_iterator;
-  typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >::
-                            const_iterator const_remapped_file_buffer_iterator;
-  remapped_file_buffer_iterator remapped_file_buffer_begin() {
-    return RemappedFileBuffers.begin();
-  }
-  const_remapped_file_buffer_iterator remapped_file_buffer_begin() const {
-    return RemappedFileBuffers.begin();
-  }
-  remapped_file_buffer_iterator remapped_file_buffer_end() {
-    return RemappedFileBuffers.end();
-  }
-  const_remapped_file_buffer_iterator remapped_file_buffer_end() const {
-    return RemappedFileBuffers.end();
-  }
-  
 public:
   PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
                           DisablePCHValidation(false),
@@ -193,20 +158,11 @@
   void addRemappedFile(StringRef From, StringRef To) {
     RemappedFiles.push_back(std::make_pair(From, To));
   }
-  
-  remapped_file_iterator eraseRemappedFile(remapped_file_iterator Remapped) {
-    return RemappedFiles.erase(Remapped);
-  }
-  
-  void addRemappedFile(StringRef From, const llvm::MemoryBuffer * To) {
+
+  void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) {
     RemappedFileBuffers.push_back(std::make_pair(From, To));
   }
-  
-  remapped_file_buffer_iterator
-  eraseRemappedFile(remapped_file_buffer_iterator Remapped) {
-    return RemappedFileBuffers.erase(Remapped);
-  }
-  
+
   void clearRemappedFiles() {
     RemappedFiles.clear();
     RemappedFileBuffers.clear();
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 83fa1a5..6f4b64d 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -20,6 +20,7 @@
 #include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/Sema.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
@@ -161,6 +162,7 @@
   std::unique_ptr<PragmaHandler> MSCodeSeg;
   std::unique_ptr<PragmaHandler> MSSection;
   std::unique_ptr<PragmaHandler> OptimizeHandler;
+  std::unique_ptr<PragmaHandler> LoopHintHandler;
 
   std::unique_ptr<CommentHandler> CommentSemaHandler;
 
@@ -262,7 +264,7 @@
   typedef clang::TypeResult        TypeResult;
 
   typedef Expr *ExprArg;
-  typedef llvm::MutableArrayRef<Stmt*> MultiStmtArg;
+  typedef MutableArrayRef<Stmt*> MultiStmtArg;
   typedef Sema::FullExprArg FullExprArg;
 
   ExprResult ExprError() { return ExprResult(true); }
@@ -519,6 +521,10 @@
   /// #pragma clang __debug captured
   StmtResult HandlePragmaCaptured();
 
+  /// \brief Handle the annotation token produced for
+  /// #pragma vectorize...
+  LoopHint HandlePragmaLoopHint();
+
   /// GetLookAheadToken - This peeks ahead N tokens and returns that token
   /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
   /// returns the token after Tok, etc.
@@ -1601,6 +1607,9 @@
   StmtResult ParseReturnStatement();
   StmtResult ParseAsmStatement(bool &msAsm);
   StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
+  StmtResult ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
+                                 SourceLocation *TrailingElseLoc,
+                                 ParsedAttributesWithRange &Attrs);
 
   /// \brief Describes the behavior that should be taken for an __if_exists
   /// block.
@@ -1659,6 +1668,7 @@
   StmtResult ParseSEHTryBlockCommon(SourceLocation Loc);
   StmtResult ParseSEHExceptBlock(SourceLocation Loc);
   StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
+  StmtResult ParseSEHLeaveStatement();
 
   //===--------------------------------------------------------------------===//
   // Objective-C Statements
@@ -1682,7 +1692,8 @@
     DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
     DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
     DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
-    DSC_top_level // top-level/namespace declaration context
+    DSC_top_level, // top-level/namespace declaration context
+    DSC_template_type_arg // template type argument context
   };
 
   /// Is this a context in which we are parsing just a type-specifier (or
@@ -1694,6 +1705,7 @@
     case DSC_top_level:
       return false;
 
+    case DSC_template_type_arg:
     case DSC_type_specifier:
     case DSC_trailing:
     case DSC_alias_declaration:
@@ -1816,6 +1828,9 @@
     return isDeclarationSpecifier(true);
   }
 
+  /// \brief Determine whether this is a C++1z for-range-identifier.
+  bool isForRangeIdentifier();
+
   /// \brief Determine whether we are currently at the start of an Objective-C
   /// class message that appears to be missing the open bracket '['.
   bool isStartOfObjCClassMessageMissingOpenBracket();
@@ -1995,6 +2010,10 @@
   // for example, attributes appertain to decl specifiers.
   void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs);
 
+  /// \brief Skip C++11 attributes and return the end location of the last one.
+  /// \returns SourceLocation() if there are no attributes.
+  SourceLocation SkipCXX11Attributes();
+
   /// \brief Diagnose and skip C++11 attributes that appear in syntactic
   /// locations where attributes are not allowed.
   void DiagnoseAndSkipCXX11Attributes();
@@ -2196,6 +2215,7 @@
          SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
          SourceLocation &EllipsisLoc);
   void ParseBracketDeclarator(Declarator &D);
+  void ParseMisplacedBracketDeclarator(Declarator &D);
 
   //===--------------------------------------------------------------------===//
   // C++ 7: Declarations [dcl.dcl]
@@ -2327,6 +2347,17 @@
   /// \param Kind Kind of current clause.
   ///
   OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind);
+  /// \brief Parses clause with a single expression and an additional argument
+  /// of a kind \a Kind.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind);
+  /// \brief Parses clause without any additional arguments.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind);
   /// \brief Parses clause with the list of variables of a kind \a Kind.
   ///
   /// \param Kind Kind of current clause.
@@ -2371,6 +2402,12 @@
   Decl *ParseTypeParameter(unsigned Depth, unsigned Position);
   Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
   Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
+  void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
+                                 SourceLocation CorrectLoc,
+                                 bool AlreadyHasEllipsis,
+                                 bool IdentifierHasName);
+  void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
+                                             Declarator &D);
   // C++ 14.3: Template arguments [temp.arg]
   typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
 
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 6872ccc..24e4cd4 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -80,7 +80,9 @@
     /// __declspec(...)
     AS_Declspec,
     /// __ptr16, alignas(...), etc.
-    AS_Keyword
+    AS_Keyword,
+    /// #pragma ...
+    AS_Pragma
   };
 
 private:
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 99941b2..8364dfc 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -814,8 +814,8 @@
   void setSetterName(IdentifierInfo *name) { SetterName = name; }
 
 private:
-  // FIXME: These two are unrelated and mutially exclusive. So perhaps
-  // we can put them in a union to reflect their mutual exclusiveness
+  // FIXME: These two are unrelated and mutually exclusive. So perhaps
+  // we can put them in a union to reflect their mutual exclusivity
   // (space saving is negligible).
   ObjCDeclQualifier objcDeclQualifier : 6;
 
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index d33a723..85551f8 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -127,7 +127,8 @@
                                             const NamedDecl *D,
                                             const ObjCInterfaceDecl *UnknownObjCClass,
                                             const ObjCPropertyDecl  *ObjCProperty,
-                                            StringRef Msg);
+                                            StringRef Msg,
+                                            bool ObjCPropertyAccess);
 
 
   static DelayedDiagnostic makeAccess(SourceLocation Loc,
@@ -202,6 +203,10 @@
   const ObjCPropertyDecl *getObjCProperty() const {
     return DeprecationData.ObjCProperty;
   }
+    
+  bool getObjCPropertyAccess() const {
+    return DeprecationData.ObjCPropertyAccess;
+  }
   
 private:
 
@@ -211,6 +216,7 @@
     const ObjCPropertyDecl  *ObjCProperty;
     const char *Message;
     size_t MessageLen;
+    bool ObjCPropertyAccess;
   };
 
   struct FTD {
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 64e3745..1b59d2d 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -401,6 +401,13 @@
     return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
   }
 
+  /// \brief If this is an array, vector, or complex number element, get the
+  /// element's index.
+  unsigned getElementIndex() const {
+    assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
+           getKind() == EK_ComplexElement);
+    return Index;
+  }
   /// \brief If this is already the initializer for an array or vector
   /// element, sets the element index.
   void setElementIndex(unsigned Index) {
@@ -851,17 +858,17 @@
   ///
   /// \param Args the argument(s) provided for initialization.
   ///
-  /// \param InInitList true if we are initializing from an expression within
-  ///        an initializer list. This disallows narrowing conversions in C++11
-  ///        onwards.
+  /// \param TopLevelOfInitList true if we are initializing from an expression
+  ///        at the top level inside an initializer list. This disallows
+  ///        narrowing conversions in C++11 onwards.
   InitializationSequence(Sema &S, 
                          const InitializedEntity &Entity,
                          const InitializationKind &Kind,
                          MultiExprArg Args,
-                         bool InInitList = false);
+                         bool TopLevelOfInitList = false);
   void InitializeFrom(Sema &S, const InitializedEntity &Entity,
                       const InitializationKind &Kind, MultiExprArg Args,
-                      bool InInitList);
+                      bool TopLevelOfInitList);
 
   ~InitializationSequence();
   
diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Sema/LoopHint.h
new file mode 100644
index 0000000..928cfb1
--- /dev/null
+++ b/include/clang/Sema/LoopHint.h
@@ -0,0 +1,31 @@
+//===--- LoopHint.h - Types for LoopHint ------------------------*- 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_SEMA_LOOPHINT_H
+#define LLVM_CLANG_SEMA_LOOPHINT_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/AttributeList.h"
+#include "clang/Sema/Ownership.h"
+
+namespace clang {
+
+/// \brief Loop hint specified by a pragma loop directive.
+struct LoopHint {
+  SourceRange Range;
+  Expr *ValueExpr;
+  IdentifierLoc *LoopLoc;
+  IdentifierLoc *ValueLoc;
+  IdentifierLoc *OptionLoc;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_LOOPHINT_H
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 9618f8f..7b9f95d 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -262,7 +262,7 @@
     StandardConversionSequence Before;
 
     /// EllipsisConversion - When this is true, it means user-defined
-    /// conversion sequence starts with a ... (elipsis) conversion, instead of 
+    /// conversion sequence starts with a ... (ellipsis) conversion, instead of
     /// a standard conversion. In this case, 'Before' field must be ignored.
     // FIXME. I much rather put this as the first field. But there seems to be
     // a gcc code gen. bug which causes a crash in a test. Putting it here seems
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index 189c5af..8031562 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -161,10 +161,7 @@
     bool isUnset() const { return !Invalid && !Val; }
 
     PtrTy get() const { return Val; }
-    // FIXME: Replace with get.
-    PtrTy release() const { return Val; }
-    PtrTy take() const { return Val; }
-    template <typename T> T *takeAs() { return static_cast<T*>(get()); }
+    template <typename T> T *getAs() { return static_cast<T*>(get()); }
 
     void set(PtrTy V) { Val = V; }
 
@@ -206,10 +203,7 @@
       void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
       return PtrTraits::getFromVoidPointer(VP);
     }
-    // FIXME: Replace with get.
-    PtrTy take() const { return get(); }
-    PtrTy release() const { return get(); }
-    template <typename T> T *takeAs() { return static_cast<T*>(get()); }
+    template <typename T> T *getAs() { return static_cast<T*>(get()); }
 
     void set(PtrTy V) {
       void *VP = PtrTraits::getAsVoidPointer(V);
@@ -264,11 +258,11 @@
   typedef ActionResult<Decl*> DeclResult;
   typedef OpaquePtr<TemplateName> ParsedTemplateTy;
 
-  typedef llvm::MutableArrayRef<Expr*> MultiExprArg;
-  typedef llvm::MutableArrayRef<Stmt*> MultiStmtArg;
-  typedef llvm::MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr;
-  typedef llvm::MutableArrayRef<ParsedType> MultiTypeArg;
-  typedef llvm::MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg;
+  typedef MutableArrayRef<Expr*> MultiExprArg;
+  typedef MutableArrayRef<Stmt*> MultiStmtArg;
+  typedef MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr;
+  typedef MutableArrayRef<ParsedType> MultiTypeArg;
+  typedef MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg;
 
   inline ExprResult ExprError() { return ExprResult(true); }
   inline StmtResult StmtError() { return StmtResult(true); }
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index d1867b3..27067a1 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -101,22 +101,36 @@
     /// \brief This is the scope for a function-level C++ try or catch scope.
     FnTryCatchScope = 0x4000,
 
-    /// \brief This is the scope of OpenMP executable directive
-    OpenMPDirectiveScope = 0x8000
+    /// \brief This is the scope of OpenMP executable directive.
+    OpenMPDirectiveScope = 0x8000,
+
+    /// \brief This is the scope of some OpenMP loop directive.
+    OpenMPLoopDirectiveScope = 0x10000,
+
+    /// \brief This is the scope of some OpenMP simd directive.
+    /// For example, it is used for 'omp simd', 'omp for simd'.
+    /// This flag is propagated to children scopes.
+    OpenMPSimdDirectiveScope = 0x20000,
+
+    /// This scope corresponds to an enum.
+    EnumScope = 0x40000,
+
+    /// This scope corresponds to a SEH try.
+    SEHTryScope = 0x80000,
   };
 private:
   /// The parent scope for this scope.  This is null for the translation-unit
   /// scope.
   Scope *AnyParent;
 
+  /// Flags - This contains a set of ScopeFlags, which indicates how the scope
+  /// interrelates with other control flow statements.
+  unsigned Flags;
+
   /// Depth - This is the depth of this scope.  The translation-unit scope has
   /// depth 0.
   unsigned short Depth;
 
-  /// Flags - This contains a set of ScopeFlags, which indicates how the scope
-  /// interrelates with other control flow statements.
-  unsigned short Flags;
-
   /// \brief Declarations with static linkage are mangled with the number of
   /// scopes seen as a component.
   unsigned short MSLocalManglingNumber;
@@ -360,9 +374,36 @@
     return (getFlags() & Scope::OpenMPDirectiveScope);
   }
 
+  /// \brief Determine whether this scope is some OpenMP loop directive scope
+  /// (for example, 'omp for', 'omp simd').
+  bool isOpenMPLoopDirectiveScope() const {
+    if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
+      assert(isOpenMPDirectiveScope() &&
+             "OpenMP loop directive scope is not a directive scope");
+      return true;
+    }
+    return false;
+  }
+
+  /// \brief Determine whether this scope is (or is nested into) some OpenMP
+  /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
+  bool isOpenMPSimdDirectiveScope() const {
+    return getFlags() & Scope::OpenMPSimdDirectiveScope;
+  }
+
+  /// \brief Determine whether this scope is a loop having OpenMP loop
+  /// directive attached.
+  bool isOpenMPLoopScope() const {
+    const Scope *P = getParent();
+    return P && P->isOpenMPLoopDirectiveScope();
+  }
+
   /// \brief Determine whether this scope is a C++ 'try' block.
   bool isTryScope() const { return getFlags() & Scope::TryScope; }
 
+  /// \brief Determine whether this scope is a SEH '__try' block.
+  bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
+
   /// containedInPrototypeScope - Return true if this or a parent scope
   /// is a FunctionPrototypeScope.
   bool containedInPrototypeScope() const;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index ecb405c..c771ff9 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -48,7 +48,6 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
 #include <deque>
 #include <memory>
 #include <string>
@@ -59,6 +58,7 @@
   template <typename ValueT> struct DenseMapInfo;
   template <typename ValueT, typename ValueInfoT> class DenseSet;
   class SmallBitVector;
+  class InlineAsmIdentifierInfo;
 }
 
 namespace clang {
@@ -928,9 +928,6 @@
     bool OldFPContractState : 1;
   };
 
-  typedef llvm::MCAsmParserSemaCallback::InlineAsmIdentifierInfo
-    InlineAsmIdentifierInfo;
-
   void addImplicitTypedef(StringRef Name, QualType T);
 
 public:
@@ -1036,10 +1033,6 @@
   /// \brief Retrieve the module loader associated with the preprocessor.
   ModuleLoader &getModuleLoader() const;
 
-  ExprResult Owned(Expr* E) { return E; }
-  ExprResult Owned(ExprResult R) { return R; }
-  StmtResult Owned(Stmt* S) { return S; }
-
   void ActOnEndOfTranslationUnit();
 
   void CheckDelegatingCtorCycles();
@@ -1157,7 +1150,7 @@
   /// unqualified type will always be a FunctionProtoType.
   /// Otherwise, returns a NULL type.
   QualType BuildFunctionType(QualType T,
-                             llvm::MutableArrayRef<QualType> ParamTypes,
+                             MutableArrayRef<QualType> ParamTypes,
                              SourceLocation Loc, DeclarationName Entity,
                              const FunctionProtoType::ExtProtoInfo &EPI);
 
@@ -1415,13 +1408,20 @@
                          IdentifierInfo **CorrectedII = nullptr);
   TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
   bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S);
-  bool DiagnoseUnknownTypeName(IdentifierInfo *&II,
+  void DiagnoseUnknownTypeName(IdentifierInfo *&II,
                                SourceLocation IILoc,
                                Scope *S,
                                CXXScopeSpec *SS,
                                ParsedType &SuggestedType,
                                bool AllowClassTemplates = false);
 
+  /// \brief For compatibility with MSVC, we delay parsing of some default
+  /// template type arguments until instantiation time.  Emits a warning and
+  /// returns a synthesized DependentNameType that isn't really dependent on any
+  /// other template arguments.
+  ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II,
+                                            SourceLocation NameLoc);
+
   /// \brief Describes the result of the name lookup and resolution performed
   /// by \c ClassifyName().
   enum NameClassificationKind {
@@ -1556,6 +1556,14 @@
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
                                     DeclarationName Name,
                                     SourceLocation Loc);
+  void
+  diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
+                            SourceLocation FallbackLoc,
+                            SourceLocation ConstQualLoc = SourceLocation(),
+                            SourceLocation VolatileQualLoc = SourceLocation(),
+                            SourceLocation RestrictQualLoc = SourceLocation(),
+                            SourceLocation AtomicQualLoc = SourceLocation());
+
   static bool adjustContextForLocalExternDecl(DeclContext *&DC);
   void DiagnoseFunctionSpecifiers(const DeclSpec &DS);
   void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
@@ -1622,12 +1630,16 @@
   void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto);
   void ActOnInitializerError(Decl *Dcl);
   void ActOnCXXForRangeDecl(Decl *D);
+  StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
+                                        IdentifierInfo *Ident,
+                                        ParsedAttributes &Attrs,
+                                        SourceLocation AttrEnd);
   void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc);
   void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc);
   void FinalizeDeclaration(Decl *D);
   DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
                                          ArrayRef<Decl *> Group);
-  DeclGroupPtrTy BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group,
+  DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
                                       bool TypeMayContainAuto = true);
 
   /// Should be called on all declarations that might have attached
@@ -2950,13 +2962,13 @@
     return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation());
   }
   FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
-    return FullExprArg(ActOnFinishFullExpr(Arg, CC).release());
+    return FullExprArg(ActOnFinishFullExpr(Arg, CC).get());
   }
   FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) {
     ExprResult FE =
       ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
                           /*DiscardedValue*/ true);
-    return FullExprArg(FE.release());
+    return FullExprArg(FE.get());
   }
 
   StmtResult ActOnExprStmt(ExprResult Arg);
@@ -3100,7 +3112,7 @@
   ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS,
                                        SourceLocation TemplateKWLoc,
                                        UnqualifiedId &Id,
-                                       InlineAsmIdentifierInfo &Info,
+                                       llvm::InlineAsmIdentifierInfo &Info,
                                        bool IsUnevaluatedContext);
   bool LookupInlineAsmField(StringRef Base, StringRef Member,
                             unsigned &Offset, SourceLocation AsmLoc);
@@ -3154,13 +3166,11 @@
   StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ?
                               SourceLocation TryLoc, Stmt *TryBlock,
                               Stmt *Handler);
-
   StmtResult ActOnSEHExceptBlock(SourceLocation Loc,
                                  Expr *FilterExpr,
                                  Stmt *Block);
-
-  StmtResult ActOnSEHFinallyBlock(SourceLocation Loc,
-                                  Stmt *Block);
+  StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, Stmt *Block);
+  StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope);
 
   void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
 
@@ -3211,7 +3221,8 @@
                                NamedDecl *D, StringRef Message,
                                SourceLocation Loc,
                                const ObjCInterfaceDecl *UnknownObjCClass,
-                               const ObjCPropertyDecl  *ObjCProperty);
+                               const ObjCPropertyDecl  *ObjCProperty,
+                               bool ObjCPropertyAccess);
 
   void HandleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
 
@@ -3223,7 +3234,8 @@
 
   bool CanUseDecl(NamedDecl *D);
   bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
-                         const ObjCInterfaceDecl *UnknownObjCClass=nullptr);
+                         const ObjCInterfaceDecl *UnknownObjCClass=nullptr,
+                         bool ObjCPropertyAccess=false);
   void NoteDeletedFunction(FunctionDecl *FD);
   std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
   bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
@@ -3403,9 +3415,10 @@
                                   const LookupResult &R,
                                   bool HasTrailingLParen);
 
-  ExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                         const DeclarationNameInfo &NameInfo,
-                                               bool IsAddressOfOperand);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+      CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo,
+      bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
+
   ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
                                        SourceLocation TemplateKWLoc,
                                 const DeclarationNameInfo &NameInfo,
@@ -3439,7 +3452,7 @@
 
   /// ActOnStringLiteral - The specified tokens were lexed as pasted string
   /// fragments (e.g. "foo" "bar" L"baz").
-  ExprResult ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks,
+  ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks,
                                 Scope *UDLScope = nullptr);
 
   ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc,
@@ -3497,14 +3510,6 @@
   ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
                                              Expr *Idx, SourceLocation RLoc);
 
-  ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
-                                      SourceLocation OpLoc, bool IsArrow,
-                                      CXXScopeSpec &SS,
-                                      SourceLocation TemplateKWLoc,
-                                      NamedDecl *FirstQualifierInScope,
-                                const DeclarationNameInfo &NameInfo,
-                                const TemplateArgumentListInfo *TemplateArgs);
-
   // This struct is for use by ActOnMemberAccess to allow
   // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after
   // changing the access operator from a '.' to a '->' (to see if that is the
@@ -3517,6 +3522,13 @@
     bool HasTrailingLParen;
   };
 
+  ExprResult BuildMemberReferenceExpr(
+      Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
+      CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+      NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
+      const TemplateArgumentListInfo *TemplateArgs,
+      ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
+
   ExprResult
   BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc,
                            bool IsArrow, const CXXScopeSpec &SS,
@@ -3527,11 +3539,6 @@
                            ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
 
   ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
-  ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base,
-                              bool &IsArrow, SourceLocation OpLoc,
-                              CXXScopeSpec &SS,
-                              Decl *ObjCImpDecl,
-                              bool HasTemplateArgs);
 
   bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
                                      const CXXScopeSpec &SS,
@@ -3932,7 +3939,7 @@
         ///   potential exceptions of the special member function contains "any"
         EPI.ExceptionSpecType = EST_ComputedNoexcept;
         EPI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
-                                                     tok::kw_false).take();
+                                                     tok::kw_false).get();
       }
     }
     FunctionProtoType::ExtProtoInfo getEPI() const {
@@ -4747,7 +4754,8 @@
                                          SourceLocation AtLoc,
                                          SourceLocation SelLoc,
                                          SourceLocation LParenLoc,
-                                         SourceLocation RParenLoc);
+                                         SourceLocation RParenLoc,
+                                         bool WarnMultipleSelectors);
 
   /// ParseObjCProtocolExpression - Build protocol expression for \@protocol
   ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
@@ -5184,7 +5192,7 @@
   void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
   TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl);
 
-  Decl *ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+  Decl *ActOnTypeParameter(Scope *S, bool Typename,
                            SourceLocation EllipsisLoc,
                            SourceLocation KeyLoc,
                            IdentifierInfo *ParamName,
@@ -5403,7 +5411,7 @@
   };
 
   bool CheckTemplateArgument(NamedDecl *Param,
-                             const TemplateArgumentLoc &Arg,
+                             TemplateArgumentLoc &Arg,
                              NamedDecl *Template,
                              SourceLocation TemplateLoc,
                              SourceLocation RAngleLoc,
@@ -5439,7 +5447,7 @@
                            SmallVectorImpl<TemplateArgument> &Converted);
 
   bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
-                                 const TemplateArgumentLoc &Arg,
+                                 TemplateArgumentLoc &Arg,
                            SmallVectorImpl<TemplateArgument> &Converted);
 
   bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
@@ -5449,7 +5457,7 @@
                                    TemplateArgument &Converted,
                                CheckTemplateArgumentKind CTAK = CTAK_Specified);
   bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
-                             const TemplateArgumentLoc &Arg,
+                             TemplateArgumentLoc &Arg,
                              unsigned ArgumentPackIndex);
 
   ExprResult
@@ -7023,6 +7031,8 @@
   
   void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr);
   
+  void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr);
+  
   bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
                                      CastKind &Kind);
   
@@ -7268,14 +7278,15 @@
   /// \brief Initialization of data-sharing attributes stack.
   void InitDataSharingAttributesStack();
   void DestroyDataSharingAttributesStack();
-  ExprResult PerformImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op);
   ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op,
                                                    OpenMPClauseKind CKind);
 public:
+  ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
+                                                    Expr *Op);
   /// \brief Called on start of new data sharing attribute block.
   void StartOpenMPDSABlock(OpenMPDirectiveKind K,
-                           const DeclarationNameInfo &DirName,
-                           Scope *CurScope);
+                           const DeclarationNameInfo &DirName, Scope *CurScope,
+                           SourceLocation Loc);
   /// \brief Called on end of data sharing attribute block.
   void EndOpenMPDSABlock(Stmt *CurDirective);
 
@@ -7294,9 +7305,8 @@
                                      SourceLocation Loc,
                                      ArrayRef<Expr *> VarList);
 
-  // brief Initialization of captured region for OpenMP parallel region.
-  void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, SourceLocation Loc,
-                              Scope *CurScope);
+  // brief Initialization of captured region for OpenMP region.
+  void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);
   StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
                                             ArrayRef<OMPClause *> Clauses,
                                             Stmt *AStmt,
@@ -7310,10 +7320,42 @@
                                           SourceLocation EndLoc);
   /// \brief Called on well-formed '\#pragma omp simd' after parsing
   /// of the associated statement.
-  StmtResult ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses,
-                                      Stmt *AStmt,
-                                      SourceLocation StartLoc,
-                                      SourceLocation EndLoc);
+  StmtResult ActOnOpenMPSimdDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp for' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPForDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp sections' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                          Stmt *AStmt, SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp section' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp single' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
+                                        Stmt *AStmt, SourceLocation StartLoc,
+                                        SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp parallel for' after parsing
+  /// of the  associated statement.
+  StmtResult ActOnOpenMPParallelForDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp parallel sections' after
+  /// parsing of the  associated statement.
+  StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                                  Stmt *AStmt,
+                                                  SourceLocation StartLoc,
+                                                  SourceLocation EndLoc);
 
   OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
                                          Expr *Expr,
@@ -7335,7 +7377,8 @@
                                       SourceLocation LParenLoc,
                                       SourceLocation EndLoc);
   /// \brief Called on well-formed 'collapse' clause.
-  OMPClause *ActOnOpenMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+  OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops,
+                                       SourceLocation StartLoc,
                                        SourceLocation LParenLoc,
                                        SourceLocation EndLoc);
 
@@ -7358,13 +7401,37 @@
                                        SourceLocation LParenLoc,
                                        SourceLocation EndLoc);
 
-  OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
-                                      ArrayRef<Expr *> Vars,
-                                      Expr *TailExpr,
-                                      SourceLocation StartLoc,
-                                      SourceLocation LParenLoc,
-                                      SourceLocation ColonLoc,
+  OMPClause *ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
+                                                unsigned Argument, Expr *Expr,
+                                                SourceLocation StartLoc,
+                                                SourceLocation LParenLoc,
+                                                SourceLocation ArgumentLoc,
+                                                SourceLocation CommaLoc,
+                                                SourceLocation EndLoc);
+  /// \brief Called on well-formed 'schedule' clause.
+  OMPClause *ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind,
+                                       Expr *ChunkSize, SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation KindLoc,
+                                       SourceLocation CommaLoc,
+                                       SourceLocation EndLoc);
+
+  OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc,
+                               SourceLocation EndLoc);
+  /// \brief Called on well-formed 'ordered' clause.
+  OMPClause *ActOnOpenMPOrderedClause(SourceLocation StartLoc,
                                       SourceLocation EndLoc);
+  /// \brief Called on well-formed 'nowait' clause.
+  OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc,
+                                     SourceLocation EndLoc);
+
+  OMPClause *
+  ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> Vars,
+                           Expr *TailExpr, SourceLocation StartLoc,
+                           SourceLocation LParenLoc, SourceLocation ColonLoc,
+                           SourceLocation EndLoc,
+                           CXXScopeSpec &ReductionIdScopeSpec,
+                           const DeclarationNameInfo &ReductionId);
   /// \brief Called on well-formed 'private' clause.
   OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
                                       SourceLocation StartLoc,
@@ -7375,11 +7442,23 @@
                                            SourceLocation StartLoc,
                                            SourceLocation LParenLoc,
                                            SourceLocation EndLoc);
+  /// \brief Called on well-formed 'lastprivate' clause.
+  OMPClause *ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
+                                          SourceLocation StartLoc,
+                                          SourceLocation LParenLoc,
+                                          SourceLocation EndLoc);
   /// \brief Called on well-formed 'shared' clause.
   OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
                                      SourceLocation StartLoc,
                                      SourceLocation LParenLoc,
                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'reduction' clause.
+  OMPClause *
+  ActOnOpenMPReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+                             SourceLocation LParenLoc, SourceLocation ColonLoc,
+                             SourceLocation EndLoc,
+                             CXXScopeSpec &ReductionIdScopeSpec,
+                             const DeclarationNameInfo &ReductionId);
   /// \brief Called on well-formed 'linear' clause.
   OMPClause *ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList,
                                      Expr *Step,
@@ -7387,11 +7466,23 @@
                                      SourceLocation LParenLoc,
                                      SourceLocation ColonLoc,
                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'aligned' clause.
+  OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
+                                      Expr *Alignment,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation ColonLoc,
+                                      SourceLocation EndLoc);
   /// \brief Called on well-formed 'copyin' clause.
   OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
                                      SourceLocation StartLoc,
                                      SourceLocation LParenLoc,
                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'copyprivate' clause.
+  OMPClause *ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
+                                          SourceLocation StartLoc,
+                                          SourceLocation LParenLoc,
+                                          SourceLocation EndLoc);
 
   /// \brief The kind of conversion being performed.
   enum CheckedConversionKind {
@@ -7696,11 +7787,11 @@
   QualType FindCompositePointerType(SourceLocation Loc,
                                     ExprResult &E1, ExprResult &E2,
                                     bool *NonStandardCompositeType = nullptr) {
-    Expr *E1Tmp = E1.take(), *E2Tmp = E2.take();
+    Expr *E1Tmp = E1.get(), *E2Tmp = E2.get();
     QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp,
                                                   NonStandardCompositeType);
-    E1 = Owned(E1Tmp);
-    E2 = Owned(E2Tmp);
+    E1 = E1Tmp;
+    E2 = E2Tmp;
     return Composite;
   }
 
@@ -7797,7 +7888,9 @@
   ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
                                              QualType castType, Expr *&op,
                                              CheckedConversionKind CCK,
-                                             bool DiagnoseCFAudited = false);
+                                             bool DiagnoseCFAudited = false,
+                                             BinaryOperatorKind Opc = BO_PtrMemD
+                                             );
 
   Expr *stripARCUnbridgedCast(Expr *e);
   void diagnoseARCUnbridgedCast(Expr *e);
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 4ee1047..9199b0f 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -27,8 +27,8 @@
 
 inline bool
 FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI) {
-  return FTI.NumParams == 1 && !FTI.isVariadic && FTI.Params[0].Ident == 0 &&
-         FTI.Params[0].Param &&
+  return FTI.NumParams == 1 && !FTI.isVariadic &&
+         FTI.Params[0].Ident == nullptr && FTI.Params[0].Param &&
          cast<ParmVarDecl>(FTI.Params[0].Param)->getType()->isVoidType();
 }
 
@@ -74,6 +74,18 @@
 
   Var->markUsed(SemaRef.Context);
 }
+
+/// Return a DLL attribute from the declaration.
+inline InheritableAttr *getDLLAttr(Decl *D) {
+  assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) &&
+         "A declaration cannot be both dllimport and dllexport.");
+  if (auto *Import = D->getAttr<DLLImportAttr>())
+    return Import;
+  if (auto *Export = D->getAttr<DLLExportAttr>())
+    return Export;
+  return nullptr;
+}
+
 }
 
 #endif
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index 03fb523..c08a5df 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -319,7 +319,7 @@
     /// \param D The declaration whose instantiation we are searching for.
     ///
     /// \returns A pointer to the declaration or argument pack of declarations
-    /// to which the declaration \c D is instantiataed, if found. Otherwise,
+    /// to which the declaration \c D is instantiated, if found. Otherwise,
     /// returns NULL.
     llvm::PointerUnion<Decl *, DeclArgumentPack *> *
     findInstantiationOf(const Decl *D);
@@ -493,7 +493,7 @@
     Decl *VisitVarTemplateSpecializationDecl(
         VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
         const TemplateArgumentListInfo &TemplateArgsInfo,
-        llvm::ArrayRef<TemplateArgument> Converted);
+        ArrayRef<TemplateArgument> Converted);
 
     Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
     ClassTemplatePartialSpecializationDecl *
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index 6a51314..2c2c36d 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -19,6 +19,7 @@
 
 namespace clang {
 
+struct DeducedPack;
 class TemplateArgumentList;
 class Sema;
 
@@ -162,6 +163,11 @@
   ///   an overloaded function which could not be resolved to a specific
   ///   function.
   Expr *Expression;
+
+  /// \brief Information on packs that we're currently expanding.
+  ///
+  /// FIXME: This should be kept internal to SemaTemplateDeduction.
+  SmallVector<DeducedPack *, 8> PendingDeducedPacks;
 };
 
 } // end namespace sema
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index e5f8f4d..6cab59c 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -250,8 +250,8 @@
   CorrectionCandidateCallback()
       : WantTypeSpecifiers(true), WantExpressionKeywords(true),
         WantCXXNamedCasts(true), WantRemainingKeywords(true),
-        WantObjCSuper(false),
-        IsObjCIvarLookup(false) {}
+        WantObjCSuper(false), IsObjCIvarLookup(false),
+        IsAddressOfOperand(false) {}
 
   virtual ~CorrectionCandidateCallback() {}
 
@@ -287,6 +287,7 @@
   // Temporary hack for the one case where a CorrectTypoContext enum is used
   // when looking up results.
   bool IsObjCIvarLookup;
+  bool IsAddressOfOperand;
 };
 
 /// @brief Simple template class for restricting typo correction candidates
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 315c852..8d9cb01 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -1334,6 +1334,7 @@
       EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr
       EXPR_CXX_UUIDOF_EXPR,       // CXXUuidofExpr (of expr).
       EXPR_CXX_UUIDOF_TYPE,       // CXXUuidofExpr (of type).
+      STMT_SEH_LEAVE,             // SEHLeaveStmt
       STMT_SEH_EXCEPT,            // SEHExceptStmt
       STMT_SEH_FINALLY,           // SEHFinallyStmt
       STMT_SEH_TRY,               // SEHTryStmt
@@ -1341,6 +1342,12 @@
       // OpenMP drectives
       STMT_OMP_PARALLEL_DIRECTIVE,
       STMT_OMP_SIMD_DIRECTIVE,
+      STMT_OMP_FOR_DIRECTIVE,
+      STMT_OMP_SECTIONS_DIRECTIVE,
+      STMT_OMP_SECTION_DIRECTIVE,
+      STMT_OMP_SINGLE_DIRECTIVE,
+      STMT_OMP_PARALLEL_FOR_DIRECTIVE,
+      STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE,
 
       // ARC
       EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index be29d8f..0698b98 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -46,7 +46,6 @@
 #include <map>
 #include <memory>
 #include <string>
-#include <sys/stat.h>
 #include <utility>
 #include <vector>
 
@@ -1839,11 +1838,11 @@
 
   void
   removeOverriddenMacros(IdentifierInfo *II, AmbiguousMacros &Ambig,
-                         llvm::ArrayRef<serialization::SubmoduleID> Overrides);
+                         ArrayRef<serialization::SubmoduleID> Overrides);
 
   AmbiguousMacros *
   removeOverriddenMacros(IdentifierInfo *II,
-                         llvm::ArrayRef<serialization::SubmoduleID> Overrides);
+                         ArrayRef<serialization::SubmoduleID> Overrides);
 
   /// \brief Retrieve the macro with the given ID.
   MacroInfo *getMacro(serialization::MacroID ID);
@@ -2024,7 +2023,7 @@
   void addPendingMacroFromModule(IdentifierInfo *II,
                                  ModuleFile *M,
                                  serialization::GlobalMacroID GMacID,
-                                 llvm::ArrayRef<serialization::SubmoduleID>);
+                                 ArrayRef<serialization::SubmoduleID>);
 
   /// \brief Add a macro to deserialize its macro directive history from a PCH.
   ///
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 08c1735..3259902 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -18,6 +18,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Serialization/Module.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
 
 namespace clang { 
 
@@ -194,6 +195,7 @@
 
   /// \brief Remove the given set of modules.
   void removeModules(ModuleIterator first, ModuleIterator last,
+                     llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
                      ModuleMap *modMap);
 
   /// \brief Add an in-memory buffer the list of known buffers
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
index 507c267..26335bf 100644
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
@@ -197,7 +197,7 @@
 
 public:
   /// Returns the argument effects for a call.
-  llvm::ArrayRef<ArgEffect> getArgs() const { return Args; }
+  ArrayRef<ArgEffect> getArgs() const { return Args; }
 
   /// Returns the effects on the receiver.
   ArgEffect getReceiver() const { return Receiver; }
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 42b6ca5..978c3e2 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -141,7 +141,7 @@
   unsigned AnalyzeAll : 1;
   unsigned AnalyzerDisplayProgress : 1;
   unsigned AnalyzeNestedBlocks : 1;
-  
+
   /// \brief The flag regulates if we should eagerly assume evaluations of
   /// conditionals, thus, bifurcating the path.
   ///
@@ -202,8 +202,8 @@
   /// \sa mayInlineCXXAllocator
   Optional<bool> InlineCXXAllocator;
 
-  /// \sa mayInlineCXXContainerCtorsAndDtors
-  Optional<bool> InlineCXXContainerCtorsAndDtors;
+  /// \sa mayInlineCXXContainerMethods
+  Optional<bool> InlineCXXContainerMethods;
 
   /// \sa mayInlineCXXSharedPtrDtor
   Optional<bool> InlineCXXSharedPtrDtor;
@@ -233,6 +233,9 @@
   /// \sa reportIssuesInMainSourceFile
   Optional<bool> ReportIssuesInMainSourceFile;
 
+  /// \sa StableReportFilename
+  Optional<bool> StableReportFilename;
+
   /// \sa getGraphTrimInterval
   Optional<unsigned> GraphTrimInterval;
 
@@ -300,12 +303,12 @@
   /// accepts the values "true" and "false".
   bool mayInlineCXXAllocator();
 
-  /// Returns whether or not constructors and destructors of C++ container
-  /// objects may be considered for inlining.
+  /// Returns whether or not methods of C++ container objects may be considered
+  /// for inlining.
   ///
   /// This is controlled by the 'c++-container-inlining' config option, which
   /// accepts the values "true" and "false".
-  bool mayInlineCXXContainerCtorsAndDtors();
+  bool mayInlineCXXContainerMethods();
 
   /// Returns whether or not the destructor of C++ 'shared_ptr' may be
   /// considered for inlining.
@@ -359,6 +362,12 @@
   /// which accepts the values "true" and "false".
   bool shouldReportIssuesInMainSourceFile();
 
+  /// Returns whether or not the report filename should be random or not.
+  ///
+  /// This is controlled by the 'stable-report-filename' config option,
+  /// which accepts the values "true" and "false". Default = false
+  bool shouldWriteStableReportFilename();
+
   /// Returns whether irrelevant parts of a bug report path should be pruned
   /// out of the final output.
   ///
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 028875d..4a5426b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -56,14 +56,14 @@
   CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {}
 
   CallEventRef<T> cloneWithState(ProgramStateRef State) const {
-    return this->getPtr()->template cloneWithState<T>(State);
+    return this->get()->template cloneWithState<T>(State);
   }
 
   // Allow implicit conversions to a superclass type, since CallEventRef
   // behaves like a pointer-to-const.
   template <typename SuperT>
   operator CallEventRef<SuperT> () const {
-    return this->getPtr();
+    return this->get();
   }
 };
 
@@ -1024,7 +1024,7 @@
 
     static SimpleType
     getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
-      return Val.getPtr();
+      return Val.get();
     }
   };
 }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 143eb95..5a33bdf 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -174,8 +174,13 @@
     return Pred->getLocationContext()->getAnalysisDeclContext();
   }
 
-  /// \brief If the given node corresponds to a PostStore program point, retrieve
-  /// the location region as it was uttered in the code.
+  /// \brief Get the blockID.
+  unsigned getBlockID() const {
+    return NB.getContext().getBlock()->getBlockID();
+  }
+
+  /// \brief If the given node corresponds to a PostStore program point,
+  /// retrieve the location region as it was uttered in the code.
   ///
   /// This utility can be useful for generating extensive diagnostics, for
   /// example, for finding variables that the given symbol was assigned to.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index d0a2780..98092ef 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -164,7 +164,7 @@
                       const ProgramStateRef &state,
                       bool IsSink) {
     ID.Add(Loc);
-    ID.AddPointer(state.getPtr());
+    ID.AddPointer(state.get());
     ID.AddBoolean(IsSink);
   }
 
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index cc4f8df..815ede8 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -50,7 +50,7 @@
 /// static cl::OptionCategory MyToolCategory("My tool options");
 /// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
 /// static cl::extrahelp MoreHelp("\nMore help text...");
-/// static cl:opt<bool> YourOwnOption(...);
+/// static cl::opt<bool> YourOwnOption(...);
 /// ...
 ///
 /// int main(int argc, const char **argv) {
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
new file mode 100644
index 0000000..0380601
--- /dev/null
+++ b/include/clang/module.modulemap
@@ -0,0 +1,110 @@
+module Clang_Analysis {
+  requires cplusplus
+  umbrella "Analysis"
+
+  // This file is intended for repeated textual inclusion.
+  exclude header "Analysis/Analyses/ThreadSafetyOps.def"
+
+  module * { export * }
+}
+
+module Clang_AST {
+  requires cplusplus
+  umbrella "AST"
+
+  // These files are intended for repeated textual inclusion.
+  exclude header "AST/BuiltinTypes.def"
+  exclude header "AST/TypeLocNodes.def"
+  exclude header "AST/TypeNodes.def"
+
+  module * { export * }
+}
+
+module Clang_ASTMatchers { requires cplusplus umbrella "ASTMatchers" module * { export * } }
+
+module Clang_Basic {
+  requires cplusplus
+  umbrella "Basic"
+
+  // These files are intended for repeated textual inclusion.
+  exclude header "Basic/BuiltinsAArch64.def"
+  exclude header "Basic/BuiltinsARM64.def"
+  exclude header "Basic/BuiltinsARM.def"
+  exclude header "Basic/Builtins.def"
+  exclude header "Basic/BuiltinsHexagon.def"
+  exclude header "Basic/BuiltinsMips.def"
+  exclude header "Basic/BuiltinsNEON.def"
+  exclude header "Basic/BuiltinsNVPTX.def"
+  exclude header "Basic/BuiltinsPPC.def"
+  exclude header "Basic/BuiltinsR600.def"
+  exclude header "Basic/BuiltinsX86.def"
+  exclude header "Basic/BuiltinsXCore.def"
+  exclude header "Basic/DiagnosticOptions.def"
+  exclude header "Basic/LangOptions.def"
+  exclude header "Basic/OpenCLExtensions.def"
+  exclude header "Basic/OpenMPKinds.def"
+  exclude header "Basic/OperatorKinds.def"
+  exclude header "Basic/Sanitizers.def"
+  exclude header "Basic/TokenKinds.def"
+
+  // This file is one big layering violation.
+  exclude header "Basic/AllDiagnostics.h"
+
+  // This file includes a header from Lex.
+  exclude header "Basic/PlistSupport.h"
+
+  // FIXME: This is logically a part of Basic, but has been put in the wrong place.
+  header "StaticAnalyzer/Core/AnalyzerOptions.h"
+
+  module * { export * }
+}
+
+module Clang_CodeGen { requires cplusplus umbrella "CodeGen" module * { export * } }
+module Clang_Config { requires cplusplus umbrella "Config" module * { export * } }
+
+module Clang_Driver {
+  requires cplusplus
+  umbrella "Driver"
+
+  // This file is intended for repeated textual inclusion.
+  exclude header "Driver/Types.def"
+
+  module * { export * }
+}
+
+module Clang_Edit { requires cplusplus umbrella "Edit" module * { export * } }
+module Clang_Format { requires cplusplus umbrella "Format" module * { export * } }
+
+module Clang_Frontend {
+  requires cplusplus
+  umbrella "Frontend"
+
+  // These files are intended for repeated textual inclusion.
+  exclude header "Frontend/CodeGenOptions.def"
+  exclude header "Frontend/LangStandards.def"
+
+  module * { export * }
+}
+
+module Clang_FrontendTool { requires cplusplus umbrella "FrontendTool" module * { export * } }
+module Clang_Index { requires cplusplus umbrella "Index" module * { export * } }
+module Clang_Lex { requires cplusplus umbrella "Lex" module * { export * } }
+module Clang_Parse { requires cplusplus umbrella "Parse" module * { export * } }
+module Clang_Rewrite { requires cplusplus umbrella "Rewrite" module * { export * } }
+module Clang_Sema { requires cplusplus umbrella "Sema" module * { export * } }
+module Clang_Serialization { requires cplusplus umbrella "Serialization" module * { export * } }
+
+module Clang_StaticAnalyzer {
+  requires cplusplus
+  umbrella "StaticAnalyzer"
+
+  // This file is intended for repeated textual inclusion.
+  exclude header "StaticAnalyzer/Core/Analyses.def"
+
+  // FIXME: This is logically a part of Basic, but has been put in the wrong place.
+  exclude header "StaticAnalyzer/Core/AnalyzerOptions.h"
+
+  module * { export * }
+}
+
+module Clang_Tooling { requires cplusplus umbrella "Tooling" module * { export * } }
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index 617bb68..8a13b2e 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -312,8 +312,8 @@
                      ARCMTMacroLocs);
   pass.setNoFinalizeRemoval(NoFinalizeRemoval);
   if (!NoNSAllocReallocError)
-    Diags->setDiagnosticMapping(diag::warn_arcmt_nsalloc_realloc,
-                                diag::MAP_ERROR, SourceLocation());
+    Diags->setSeverity(diag::warn_arcmt_nsalloc_realloc, diag::Severity::Error,
+                       SourceLocation());
 
   for (unsigned i=0, e = transforms.size(); i != e; ++i)
     transforms[i](pass);
diff --git a/lib/ARCMigrate/FileRemapper.cpp b/lib/ARCMigrate/FileRemapper.cpp
index e1cebc7..40e6060 100644
--- a/lib/ARCMigrate/FileRemapper.cpp
+++ b/lib/ARCMigrate/FileRemapper.cpp
@@ -65,12 +65,13 @@
 
   std::vector<std::pair<const FileEntry *, const FileEntry *> > pairs;
 
-  std::unique_ptr<llvm::MemoryBuffer> fileBuf;
-  if (llvm::MemoryBuffer::getFile(infoFile.c_str(), fileBuf))
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBuf =
+      llvm::MemoryBuffer::getFile(infoFile.c_str());
+  if (!fileBuf)
     return report("Error opening file: " + infoFile, Diag);
   
   SmallVector<StringRef, 64> lines;
-  fileBuf->getBuffer().split(lines, "\n");
+  fileBuf.get()->getBuffer().split(lines, "\n");
 
   for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) {
     StringRef fromFilename = lines[idx];
@@ -111,7 +112,7 @@
 bool FileRemapper::flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag) {
   using namespace llvm::sys;
 
-  if (fs::create_directory(outputDir) != llvm::errc::success)
+  if (fs::create_directory(outputDir))
     return report("Could not create directory: " + outputDir, Diag);
 
   std::string infoFile = getRemapInfoFile(outputDir);
@@ -206,22 +207,6 @@
   PPOpts.RetainRemappedFileBuffers = true;
 }
 
-void FileRemapper::transferMappingsAndClear(PreprocessorOptions &PPOpts) {
-  for (MappingsTy::iterator
-         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
-    if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
-      PPOpts.addRemappedFile(I->first->getName(), FE->getName());
-    } else {
-      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
-      PPOpts.addRemappedFile(I->first->getName(), mem);
-    }
-    I->second = Target();
-  }
-
-  PPOpts.RetainRemappedFileBuffers = false;
-  clear();
-}
-
 void FileRemapper::remap(StringRef filePath, llvm::MemoryBuffer *memBuf) {
   remap(getOriginalFile(filePath), memBuf);
 }
diff --git a/lib/ARCMigrate/Internals.h b/lib/ARCMigrate/Internals.h
index d87d1ec..a65b329 100644
--- a/lib/ARCMigrate/Internals.h
+++ b/lib/ARCMigrate/Internals.h
@@ -48,7 +48,6 @@
 class TransformActions {
   DiagnosticsEngine &Diags;
   CapturedDiagList &CapturedDiags;
-  bool ReportedErrors;
   void *Impl; // TransformActionsImpl.
 
 public:
@@ -104,7 +103,9 @@
   void reportNote(StringRef note, SourceLocation loc,
                   SourceRange range = SourceRange());
 
-  bool hasReportedErrors() const { return ReportedErrors; }
+  bool hasReportedErrors() const {
+    return Diags.hasUnrecoverableErrorOccurred();
+  }
 
   class RewriteReceiver {
   public:
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index a52c32f..1a2055e 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -1359,7 +1359,7 @@
       Editor->commit(commit);
     }
   }
-  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+  ArrayRef<ArgEffect> AEArgs = CE.getArgs();
   unsigned i = 0;
   for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
@@ -1411,7 +1411,7 @@
   
   // At this point result type is audited for potential inclusion.
   // Now, how about argument types.
-  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+  ArrayRef<ArgEffect> AEArgs = CE.getArgs();
   unsigned i = 0;
   bool ArgCFAudited = false;
   for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
@@ -1488,7 +1488,7 @@
       Editor->commit(commit);
     }
   }
-  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+  ArrayRef<ArgEffect> AEArgs = CE.getArgs();
   unsigned i = 0;
   for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
@@ -1544,7 +1544,7 @@
   
   // At this point result type is either annotated or audited.
   // Now, how about argument types.
-  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+  ArrayRef<ArgEffect> AEArgs = CE.getArgs();
   unsigned i = 0;
   for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
@@ -1853,8 +1853,8 @@
   std::vector<std::string> Filenames;
   if (DirPath.empty() || !is_directory(DirPath))
     return Filenames;
-  
-  llvm::error_code EC;
+
+  std::error_code EC;
   directory_iterator DI = directory_iterator(DirPath, EC);
   directory_iterator DE;
   for (; !EC && DI != DE; DI = DI.increment(EC)) {
@@ -1943,12 +1943,13 @@
   bool parse(StringRef File, SmallVectorImpl<EditEntry> &Entries) {
     using namespace llvm::yaml;
 
-    std::unique_ptr<llvm::MemoryBuffer> FileBuf;
-    if (llvm::MemoryBuffer::getFile(File, FileBuf))
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
+        llvm::MemoryBuffer::getFile(File);
+    if (!FileBufOrErr)
       return true;
 
     llvm::SourceMgr SM;
-    Stream YAMLStream(FileBuf.release(), SM);
+    Stream YAMLStream(FileBufOrErr.get().release(), SM);
     document_iterator I = YAMLStream.begin();
     if (I == YAMLStream.end())
       return true;
diff --git a/lib/ARCMigrate/PlistReporter.cpp b/lib/ARCMigrate/PlistReporter.cpp
index 2632417..6b34ef0 100644
--- a/lib/ARCMigrate/PlistReporter.cpp
+++ b/lib/ARCMigrate/PlistReporter.cpp
@@ -16,6 +16,22 @@
 using namespace arcmt;
 using namespace markup;
 
+static StringRef getLevelName(DiagnosticsEngine::Level Level) {
+  switch (Level) {
+  case DiagnosticsEngine::Ignored:
+    llvm_unreachable("ignored");
+  case DiagnosticsEngine::Note:
+    return "note";
+  case DiagnosticsEngine::Remark:
+  case DiagnosticsEngine::Warning:
+    return "warning";
+  case DiagnosticsEngine::Fatal:
+  case DiagnosticsEngine::Error:
+    return "error";
+  }
+  llvm_unreachable("Invalid DiagnosticsEngine level!");
+}
+
 void arcmt::writeARCDiagsToPlist(const std::string &outPath,
                                  ArrayRef<StoredDiagnostic> diags,
                                  SourceManager &SM,
@@ -47,8 +63,7 @@
     return;
   }
 
-  // Write the plist header.
-  o << PlistHeader;
+  EmitPlistHeader(o);
 
   // Write the root object: a <dict> containing...
   //  - "files", an <array> mapping from FIDs to file names
@@ -57,11 +72,8 @@
        " <key>files</key>\n"
        " <array>\n";
 
-  for (SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end();
-       I!=E; ++I) {
-    o << "  ";
-    EmitString(o, SM.getFileEntryForID(*I)->getName()) << '\n';
-  }
+  for (FileID FID : Fids)
+    EmitString(o << "  ", SM.getFileEntryForID(FID)->getName()) << '\n';
 
   o << " </array>\n"
        " <key>diagnostics</key>\n"
@@ -84,12 +96,7 @@
     EmitString(o, DiagIDs.getCategoryNameFromID(
                           DiagIDs.getCategoryNumberForDiag(D.getID()))) << '\n';
     o << "   <key>type</key>";
-    if (D.getLevel() >= DiagnosticsEngine::Error)
-      EmitString(o, "error") << '\n';
-    else if (D.getLevel() == DiagnosticsEngine::Warning)
-      EmitString(o, "warning") << '\n';
-    else
-      EmitString(o, "note") << '\n';
+    EmitString(o, getLevelName(D.getLevel())) << '\n';
 
     // Output the location of the bug.
     o << "  <key>location</key>\n";
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index e6268a1..6d178be 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -601,7 +601,7 @@
 TransformActions::TransformActions(DiagnosticsEngine &diag,
                                    CapturedDiagList &capturedDiags,
                                    ASTContext &ctx, Preprocessor &PP)
-  : Diags(diag), CapturedDiags(capturedDiags), ReportedErrors(false) {
+    : Diags(diag), CapturedDiags(capturedDiags) {
   Impl = new TransformActionsImpl(capturedDiags, ctx, PP);
 }
 
@@ -677,17 +677,6 @@
                                            SourceRange range) {
   assert(!static_cast<TransformActionsImpl *>(Impl)->isInTransaction() &&
          "Errors should be emitted out of a transaction");
-
-  SourceManager &SM = static_cast<TransformActionsImpl *>(Impl)
-                          ->getASTContext()
-                          .getSourceManager();
-  DiagnosticsEngine::Level L = Diags.getDiagnosticLevel(diagId, loc);
-  // TODO: Move this check to the caller to ensure consistent note attachments.
-  if (L == DiagnosticsEngine::Ignored ||
-      SM.isInSystemHeader(SM.getExpansionLoc(loc)))
-    return DiagnosticBuilder::getEmpty();
-  if (L >= DiagnosticsEngine::Error)
-    ReportedErrors = true;
   return Diags.Report(loc, diagId) << range;
 }
 
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index e7b5a6b..0fa0216 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -403,9 +403,13 @@
 
       if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
         Out << *VD;
-      else
+      else {
+        assert(Base.get<const Expr *>() != nullptr &&
+               "Expecting non-null Expr");
         Base.get<const Expr*>()->printPretty(Out, nullptr,
                                              Ctx.getPrintingPolicy());
+      }
+
       if (!O.isZero()) {
         Out << " + " << (O / S);
         if (IsReference)
@@ -426,6 +430,7 @@
       ElemTy = VD->getType();
     } else {
       const Expr *E = Base.get<const Expr*>();
+      assert(E != nullptr && "Expecting non-null Expr");
       E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
       ElemTy = E->getType();
     }
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 2ea93ba..a1a9438 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1309,13 +1309,14 @@
 
   } else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
     QualType T = VD->getType();
-    if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
+    if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
       if (ForAlignof)
         T = RT->getPointeeType();
       else
         T = getPointerType(RT->getPointeeType());
     }
-    if (!T->isIncompleteType() && !T->isFunctionType()) {
+    QualType BaseT = getBaseElementType(T);
+    if (!BaseT->isIncompleteType() && !T->isFunctionType()) {
       // Adjust alignments of declarations with array type by the
       // large-array alignment on the target.
       if (const ArrayType *arrayType = getAsArrayType(T)) {
@@ -1327,11 +1328,6 @@
                    MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType)))
             Align = std::max(Align, Target->getLargeArrayAlign());
         }
-
-        // Keep track of extra alignment requirements on the array itself, then
-        // work with the element type.
-        Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
-        T = getBaseElementType(arrayType);
       }
       Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
       if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
@@ -1783,6 +1779,7 @@
   const TypedefType *TT = T->getAs<TypedefType>();
 
   // Double and long long should be naturally aligned if possible.
+  T = T->getBaseElementTypeUnsafe();
   if (const ComplexType *CT = T->getAs<ComplexType>())
     T = CT->getElementType().getTypePtr();
   if (T->isSpecificBuiltinType(BuiltinType::Double) ||
@@ -3318,8 +3315,6 @@
                                           NestedNameSpecifier *NNS,
                                           const IdentifierInfo *Name,
                                           QualType Canon) const {
-  assert(NNS->isDependent() && "nested-name-specifier must be dependent");
-
   if (Canon.isNull()) {
     NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
     ElaboratedTypeKeyword CanonKeyword = Keyword;
@@ -3433,7 +3428,7 @@
     // contains an alias template specialization which ignores one of its
     // parameters.
     if (Canon->containsUnexpandedParameterPack()) {
-      Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions);
+      Canon = getPackExpansionType(Canon, NumExpansions);
 
       // Find the insert position again, in case we inserted an element into
       // PackExpansionTypes and invalidated our insert position.
@@ -3444,7 +3439,7 @@
   T = new (*this) PackExpansionType(Pattern, Canon, NumExpansions);
   Types.push_back(T);
   PackExpansionTypes.InsertNode(T, InsertPos);
-  return QualType(T, 0);  
+  return QualType(T, 0);
 }
 
 /// CmpProtocolNames - Comparison predicate for sorting protocols
@@ -3687,10 +3682,10 @@
 }
 
 /// getTypeOfType -  Unlike many "get<Type>" functions, we don't unique
-/// TypeOfType AST's. The only motivation to unique these nodes would be
+/// TypeOfType nodes. The only motivation to unique these nodes would be
 /// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical type's (which are always unique).
+/// an issue. This doesn't affect the type checker, since it operates
+/// on canonical types (which are always unique).
 QualType ASTContext::getTypeOfType(QualType tofType) const {
   QualType Canonical = getCanonicalType(tofType);
   TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
@@ -3699,18 +3694,17 @@
 }
 
 
-/// getDecltypeType -  Unlike many "get<Type>" functions, we don't unique
-/// DecltypeType AST's. The only motivation to unique these nodes would be
-/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical types (which are always unique).
+/// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType
+/// nodes. This would never be helpful, since each such type has its own
+/// expression, and would not give a significant memory saving, since there
+/// is an Expr tree under each such type.
 QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
   DecltypeType *dt;
-  
-  // C++0x [temp.type]p2:
+
+  // C++11 [temp.type]p2:
   //   If an expression e involves a template parameter, decltype(e) denotes a
-  //   unique dependent type. Two such decltype-specifiers refer to the same 
-  //   type only if their expressions are equivalent (14.5.6.1). 
+  //   unique dependent type. Two such decltype-specifiers refer to the same
+  //   type only if their expressions are equivalent (14.5.6.1).
   if (e->isInstantiationDependent()) {
     llvm::FoldingSetNodeID ID;
     DependentDecltypeType::Profile(ID, *this, e);
@@ -3718,20 +3712,16 @@
     void *InsertPos = nullptr;
     DependentDecltypeType *Canon
       = DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
-    if (Canon) {
-      // We already have a "canonical" version of an equivalent, dependent
-      // decltype type. Use that as our canonical type.
-      dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
-                                       QualType((DecltypeType*)Canon, 0));
-    } else {
+    if (!Canon) {
       // Build a new, canonical typeof(expr) type.
       Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
       DependentDecltypeTypes.InsertNode(Canon, InsertPos);
-      dt = Canon;
     }
+    dt = new (*this, TypeAlignment)
+        DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0));
   } else {
-    dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType, 
-                                      getCanonicalType(UnderlyingType));
+    dt = new (*this, TypeAlignment)
+        DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType));
   }
   Types.push_back(dt);
   return QualType(dt, 0);
@@ -5032,9 +5022,7 @@
   // Encode result type.
   // GCC has some special rules regarding encoding of properties which
   // closely resembles encoding of ivars.
-  getObjCEncodingForTypeImpl(PD->getType(), S, true, true, nullptr,
-                             true /* outermost type */,
-                             true /* encoding for property */);
+  getObjCEncodingForPropertyType(PD->getType(), S);
 
   if (PD->isReadOnly()) {
     S += ",R";
@@ -5107,6 +5095,16 @@
                              true /* outermost type */);
 }
 
+void ASTContext::getObjCEncodingForPropertyType(QualType T,
+                                                std::string& S) const {
+  // Encode result type.
+  // GCC has some special rules regarding encoding of properties which
+  // closely resembles encoding of ivars.
+  getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
+                             true /* outermost type */,
+                             true /* encoding property */);
+}
+
 static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
                                             BuiltinType::Kind kind) {
     switch (kind) {
@@ -7853,14 +7851,6 @@
                                                : StaticLocalLinkage;
   }
 
-  // On Darwin, the backing variable for a C++11 thread_local variable always
-  // has internal linkage; all accesses should just be calls to the
-  // Itanium-specified entry point, which has the normal linkage of the
-  // variable.
-  if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
-      Context.getTargetInfo().getTriple().isMacOSX())
-    return GVA_Internal;
-
   switch (VD->getTemplateSpecializationKind()) {
   case TSK_Undeclared:
   case TSK_ExplicitSpecialization:
@@ -8177,10 +8167,12 @@
       if (!Node)
         return true;
       if (ParentStack.size() > 0) {
-        // FIXME: Currently we add the same parent multiple times, for example
-        // when we visit all subexpressions of template instantiations; this is
-        // suboptimal, bug benign: the only way to visit those is with
-        // hasAncestor / hasParent, and those do not create new matches.
+        // FIXME: Currently we add the same parent multiple times, but only
+        // when no memoization data is available for the type.
+        // For example when we visit all subexpressions of template
+        // instantiations; this is suboptimal, but benign: the only way to
+        // visit those is with hasAncestor / hasParent, and those do not create
+        // new matches.
         // The plan is to enable DynTypedNode to be storable in a map or hash
         // map. The main problem there is to implement hash functions /
         // comparison operators for all types that DynTypedNode supports that
@@ -8188,18 +8180,27 @@
         auto &NodeOrVector = (*Parents)[Node];
         if (NodeOrVector.isNull()) {
           NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
-        } else if (NodeOrVector
-                       .template is<ast_type_traits::DynTypedNode *>()) {
-          auto *Node =
-              NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
-          auto *Vector = new ASTContext::ParentVector(1, *Node);
-          Vector->push_back(ParentStack.back());
-          NodeOrVector = Vector;
-          delete Node;
         } else {
+          if (NodeOrVector.template is<ast_type_traits::DynTypedNode *>()) {
+            auto *Node =
+                NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
+            auto *Vector = new ASTContext::ParentVector(1, *Node);
+            NodeOrVector = Vector;
+            delete Node;
+          }
           assert(NodeOrVector.template is<ASTContext::ParentVector *>());
-          NodeOrVector.template get<ASTContext::ParentVector *>()->push_back(
-              ParentStack.back());
+
+          auto *Vector =
+              NodeOrVector.template get<ASTContext::ParentVector *>();
+          // Skip duplicates for types that have memoization data.
+          // We must check that the type has memoization data before calling
+          // std::find() because DynTypedNode::operator== can't compare all
+          // types.
+          bool Found = ParentStack.back().getMemoizationData() &&
+                       std::find(Vector->begin(), Vector->end(),
+                                 ParentStack.back()) != Vector->end();
+          if (!Found)
+            Vector->push_back(ParentStack.back());
         }
       }
       ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index bd5c209..2ee26fb 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -161,9 +162,8 @@
 /// diagnostic message
 static std::string
 ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
-                              const DiagnosticsEngine::ArgumentValue *PrevArgs,
-                              unsigned NumPrevArgs,
-                              ArrayRef<intptr_t> QualTypeVals) {
+                            ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+                            ArrayRef<intptr_t> QualTypeVals) {
   // FIXME: Playing with std::string is really slow.
   bool ForceAKA = false;
   QualType CanTy = Ty.getCanonicalType();
@@ -201,7 +201,7 @@
   // Check to see if we already desugared this type in this
   // diagnostic.  If so, don't do it again.
   bool Repeated = false;
-  for (unsigned i = 0; i != NumPrevArgs; ++i) {
+  for (unsigned i = 0, e = PrevArgs.size(); i != e; ++i) {
     // TODO: Handle ak_declcontext case.
     if (PrevArgs[i].first == DiagnosticsEngine::ak_qualtype) {
       void *Ptr = (void*)PrevArgs[i].second;
@@ -256,12 +256,9 @@
 void clang::FormatASTNodeDiagnosticArgument(
     DiagnosticsEngine::ArgumentKind Kind,
     intptr_t Val,
-    const char *Modifier,
-    unsigned ModLen,
-    const char *Argument,
-    unsigned ArgLen,
-    const DiagnosticsEngine::ArgumentValue *PrevArgs,
-    unsigned NumPrevArgs,
+    StringRef Modifier,
+    StringRef Argument,
+    ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
     SmallVectorImpl<char> &Output,
     void *Cookie,
     ArrayRef<intptr_t> QualTypeVals) {
@@ -296,28 +293,26 @@
       // Attempting to do a template diff on non-templates.  Set the variables
       // and continue with regular type printing of the appropriate type.
       Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType;
-      ModLen = 0;
-      ArgLen = 0;
+      Modifier = StringRef();
+      Argument = StringRef();
       // Fall through
     }
     case DiagnosticsEngine::ak_qualtype: {
-      assert(ModLen == 0 && ArgLen == 0 &&
+      assert(Modifier.empty() && Argument.empty() &&
              "Invalid modifier for QualType argument");
       
       QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
-      OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs,
-                                          QualTypeVals);
+      OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals);
       NeedQuotes = false;
       break;
     }
     case DiagnosticsEngine::ak_declarationname: {
-      if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0)
+      if (Modifier == "objcclass" && Argument.empty())
         OS << '+';
-      else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12)
-                && ArgLen==0)
+      else if (Modifier == "objcinstance" && Argument.empty())
         OS << '-';
       else
-        assert(ModLen == 0 && ArgLen == 0 &&
+        assert(Modifier.empty() && Argument.empty() &&
                "Invalid modifier for DeclarationName argument");
 
       OS << DeclarationName::getFromOpaqueInteger(Val);
@@ -325,10 +320,10 @@
     }
     case DiagnosticsEngine::ak_nameddecl: {
       bool Qualified;
-      if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0)
+      if (Modifier == "q" && Argument.empty())
         Qualified = true;
       else {
-        assert(ModLen == 0 && ArgLen == 0 &&
+        assert(Modifier.empty() && Argument.empty() &&
                "Invalid modifier for NamedDecl* argument");
         Qualified = false;
       }
@@ -345,7 +340,8 @@
     case DiagnosticsEngine::ak_declcontext: {
       DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
       assert(DC && "Should never have a null declaration context");
-      
+      NeedQuotes = false;
+
       if (DC->isTranslationUnit()) {
         // FIXME: Get these strings from some localized place
         if (Context.getLangOpts().CPlusPlus)
@@ -355,10 +351,17 @@
       } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
         OS << ConvertTypeToDiagnosticString(Context,
                                             Context.getTypeDeclType(Type),
-                                            PrevArgs, NumPrevArgs,
-                                            QualTypeVals);
+                                            PrevArgs, QualTypeVals);
       } else {
         // FIXME: Get these strings from some localized place
+        if (isa<BlockDecl>(DC)) {
+          OS << "block literal";
+          break;
+        }
+        if (isLambdaCallOperator(DC)) {
+          OS << "lambda expression";
+          break;
+        }
         NamedDecl *ND = cast<NamedDecl>(DC);
         if (isa<NamespaceDecl>(ND))
           OS << "namespace ";
@@ -371,7 +374,6 @@
         ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true);
         OS << '\'';
       }
-      NeedQuotes = false;
       break;
     }
     case DiagnosticsEngine::ak_attr: {
@@ -957,25 +959,27 @@
                           ToIter.isEnd() && ToExpr);
           if (DefaultNTTPD->getType()->isIntegralOrEnumerationType()) {
             if (FromExpr)
-              FromInt = GetInt(FromIter, FromExpr);
+              HasFromInt = GetInt(FromIter, FromExpr, FromInt);
             if (ToExpr)
-              ToInt = GetInt(ToIter, ToExpr);
-            Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr);
+              HasToInt = GetInt(ToIter, ToExpr, ToInt);
+          }
+          if (HasFromInt && HasToInt) {
+            Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
             Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
             Tree.SetKind(DiffTree::Integer);
+          } else if (HasFromInt || HasToInt) {
+            Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
+            Tree.SetSame(false);
+            Tree.SetKind(DiffTree::Integer);
           } else {
             Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr));
             Tree.SetKind(DiffTree::Expression);
           }
         } else if (HasFromInt || HasToInt) {
-          if (!HasFromInt && FromExpr) {
-            FromInt = GetInt(FromIter, FromExpr);
-            HasFromInt = true;
-          }
-          if (!HasToInt && ToExpr) {
-            ToInt = GetInt(ToIter, ToExpr);
-            HasToInt = true;
-          }
+          if (!HasFromInt && FromExpr)
+            HasFromInt = GetInt(FromIter, FromExpr, FromInt);
+          if (!HasToInt && ToExpr)
+            HasToInt = GetInt(ToIter, ToExpr, ToInt);
           Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
           Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
           Tree.SetDefault(FromIter.isEnd() && HasFromInt,
@@ -1119,20 +1123,28 @@
 
   /// GetInt - Retrieves the template integer argument, including evaluating
   /// default arguments.
-  llvm::APInt GetInt(const TSTiterator &Iter, Expr *ArgExpr) {
+  bool GetInt(const TSTiterator &Iter, Expr *ArgExpr, llvm::APInt &Int) {
     // Default, value-depenedent expressions require fetching
-    // from the desugared TemplateArgument
-    if (Iter.isEnd() && ArgExpr->isValueDependent())
+    // from the desugared TemplateArgument, otherwise expression needs to
+    // be evaluatable.
+    if (Iter.isEnd() && ArgExpr->isValueDependent()) {
       switch (Iter.getDesugar().getKind()) {
         case TemplateArgument::Integral:
-          return Iter.getDesugar().getAsIntegral();
+          Int = Iter.getDesugar().getAsIntegral();
+          return true;
         case TemplateArgument::Expression:
           ArgExpr = Iter.getDesugar().getAsExpr();
-          return ArgExpr->EvaluateKnownConstInt(Context);
+          Int = ArgExpr->EvaluateKnownConstInt(Context);
+          return true;
         default:
-          assert(0 && "Unexpected template argument kind");
+          llvm_unreachable("Unexpected template argument kind");
       }
-    return ArgExpr->EvaluateKnownConstInt(Context);
+    } else if (ArgExpr->isEvaluatable(Context)) {
+      Int = ArgExpr->EvaluateKnownConstInt(Context);
+      return true;
+    }
+
+    return false;
   }
 
   /// GetValueDecl - Retrieves the template Decl argument, including
@@ -1148,7 +1160,7 @@
           ArgExpr = Iter.getDesugar().getAsExpr();
           return cast<DeclRefExpr>(ArgExpr)->getDecl();
         default:
-          assert(0 && "Unexpected template argument kind");
+          llvm_unreachable("Unexpected template argument kind");
       }
     DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
     if (!DRE) {
@@ -1515,6 +1527,8 @@
         Bold();
       }
       OS << Val.toString(10);
+    } else if (E) {
+      PrintExpr(E);
     } else {
       OS << "(no argument)";
     }
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 14e0e01..9ece41d 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -315,6 +315,7 @@
     void VisitIntegerLiteral(const IntegerLiteral *Node);
     void VisitFloatingLiteral(const FloatingLiteral *Node);
     void VisitStringLiteral(const StringLiteral *Str);
+    void VisitInitListExpr(const InitListExpr *ILE);
     void VisitUnaryOperator(const UnaryOperator *Node);
     void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
     void VisitMemberExpr(const MemberExpr *Node);
@@ -629,9 +630,11 @@
   }
   dumpPointer(A);
   dumpSourceRange(A->getRange());
-#include "clang/AST/AttrDump.inc"
+  if (A->isInherited())
+    OS << " Inherited";
   if (A->isImplicit())
     OS << " Implicit";
+#include "clang/AST/AttrDump.inc"
 }
 
 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
@@ -804,6 +807,12 @@
       OS << " hidden";
   if (D->isImplicit())
     OS << " implicit";
+  if (D->isUsed())
+    OS << " used";
+  else if (D->isReferenced())
+    OS << " referenced";
+  if (D->isInvalidDecl())
+    OS << " invalid";
 
   bool HasAttrs = D->hasAttrs();
   const FullComment *Comment =
@@ -827,9 +836,6 @@
   lastChild();
   dumpFullComment(Comment);
 
-  if (D->isInvalidDecl())
-    OS << " invalid";
-
   setMoreChildren(false);
   if (HasDeclContext)
     dumpDeclContext(cast<DeclContext>(D));
@@ -1720,6 +1726,22 @@
   Str->outputString(OS);
 }
 
+void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
+  VisitExpr(ILE);
+  if (auto *Filler = ILE->getArrayFiller()) {
+    if (!ILE->getNumInits())
+      lastChild();
+    IndentScope Indent(*this);
+    OS << "array filler";
+    lastChild();
+    dumpStmt(Filler);
+  }
+  if (auto *Field = ILE->getInitializedFieldInUnion()) {
+    OS << " field ";
+    dumpBareDeclRef(Field);
+  }
+}
+
 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
   VisitExpr(Node);
   OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index b180326..b0e0b1d 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -4090,8 +4090,7 @@
   // Try to find an existing specialization with these template arguments.
   void *InsertPos = nullptr;
   ClassTemplateSpecializationDecl *D2
-    = ClassTemplate->findSpecialization(TemplateArgs.data(), 
-                                        TemplateArgs.size(), InsertPos);
+    = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
   if (D2) {
     // We already have a class template specialization with these template
     // arguments.
@@ -4284,7 +4283,7 @@
   // Try to find an existing specialization with these template arguments.
   void *InsertPos = nullptr;
   VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
-      TemplateArgs.data(), TemplateArgs.size(), InsertPos);
+      TemplateArgs, InsertPos);
   if (D2) {
     // We already have a variable template specialization with these template
     // arguments.
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 1c3a538..7448de2 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -471,6 +471,58 @@
   LV.mergeExternalVisibility(argsLV);
 }
 
+/// Should we consider visibility associated with the template
+/// arguments and parameters of the given variable template
+/// specialization? As usual, follow class template specialization
+/// logic up to initialization.
+static bool shouldConsiderTemplateVisibility(
+                                 const VarTemplateSpecializationDecl *spec,
+                                 LVComputationKind computation) {
+  // Include visibility from the template parameters and arguments
+  // only if this is not an explicit instantiation or specialization
+  // with direct explicit visibility (and note that implicit
+  // instantiations won't have a direct attribute).
+  if (!spec->isExplicitInstantiationOrSpecialization())
+    return true;
+
+  // An explicit variable specialization is an independent, top-level
+  // declaration.  As such, if it has an explicit visibility attribute,
+  // that must directly express the user's intent, and we should honor
+  // it.
+  if (spec->isExplicitSpecialization() &&
+      hasExplicitVisibilityAlready(computation))
+    return false;
+
+  return !hasDirectVisibilityAttribute(spec, computation);
+}
+
+/// Merge in template-related linkage and visibility for the given
+/// variable template specialization. As usual, follow class template
+/// specialization logic up to initialization.
+static void mergeTemplateLV(LinkageInfo &LV,
+                            const VarTemplateSpecializationDecl *spec,
+                            LVComputationKind computation) {
+  bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
+
+  // Merge information from the template parameters, but ignore
+  // visibility if we're only considering template arguments.
+
+  VarTemplateDecl *temp = spec->getSpecializedTemplate();
+  LinkageInfo tempLV =
+    getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
+  LV.mergeMaybeWithVisibility(tempLV,
+           considerVisibility && !hasExplicitVisibilityAlready(computation));
+
+  // Merge information from the template arguments.  We ignore
+  // template-argument visibility if we've got an explicit
+  // instantiation with a visibility attribute.
+  const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
+  LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
+  if (considerVisibility)
+    LV.mergeVisibility(argsLV);
+  LV.mergeExternalVisibility(argsLV);
+}
+
 static bool useInlineVisibilityHidden(const NamedDecl *D) {
   // FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
   const LangOptions &Opts = D->getASTContext().getLangOpts();
@@ -662,6 +714,14 @@
     // C99 6.2.2p4 and propagating the visibility attribute, so we don't have
     // to do it here.
 
+    // As per function and class template specializations (below),
+    // consider LV for the template and template arguments.  We're at file
+    // scope, so we do not need to worry about nested specializations.
+    if (const VarTemplateSpecializationDecl *spec
+              = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+      mergeTemplateLV(LV, spec, computation);
+    }
+
   //     - a function, unless it has internal linkage; or
   } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
     // In theory, we can modify the function's LV by the LV of its
@@ -869,6 +929,10 @@
 
   // Static data members.
   } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (const VarTemplateSpecializationDecl *spec
+        = dyn_cast<VarTemplateSpecializationDecl>(VD))
+      mergeTemplateLV(LV, spec, computation);
+
     // Modify the variable's linkage by its type, but ignore the
     // type's visibility unless it's a definition.
     LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
@@ -1303,6 +1367,9 @@
                                                             TemplateArgs.size(),
                                                             P);
     } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
+      if (P.SuppressUnwrittenScope &&
+          (ND->isAnonymousNamespace() || ND->isInline()))
+        continue;
       if (ND->isAnonymousNamespace())
         OS << "(anonymous namespace)";
       else
@@ -1676,7 +1743,7 @@
 }
 
 template<typename T>
-static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
+static LanguageLinkage getDeclLanguageLinkage(const T &D) {
   // C++ [dcl.link]p1: All function types, function names with external linkage,
   // and variable names with external linkage have a language linkage.
   if (!D.hasExternalFormalLinkage())
@@ -1704,7 +1771,7 @@
 }
 
 template<typename T>
-static bool isExternCTemplate(const T &D) {
+static bool isDeclExternC(const T &D) {
   // Since the context is ignored for class members, they can only have C++
   // language linkage or no language linkage.
   const DeclContext *DC = D.getDeclContext();
@@ -1717,11 +1784,11 @@
 }
 
 LanguageLinkage VarDecl::getLanguageLinkage() const {
-  return getLanguageLinkageTemplate(*this);
+  return getDeclLanguageLinkage(*this);
 }
 
 bool VarDecl::isExternC() const {
-  return isExternCTemplate(*this);
+  return isDeclExternC(*this);
 }
 
 bool VarDecl::isInExternCContext() const {
@@ -2345,7 +2412,7 @@
     return false;
 
   const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
-  if (FPT->getNumParams() > 2 || FPT->isVariadic())
+  if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
     return false;
 
   // If this is a single-parameter function, it must be a replaceable global
@@ -2403,11 +2470,11 @@
 }
 
 LanguageLinkage FunctionDecl::getLanguageLinkage() const {
-  return getLanguageLinkageTemplate(*this);
+  return getDeclLanguageLinkage(*this);
 }
 
 bool FunctionDecl::isExternC() const {
-  return isExternCTemplate(*this);
+  return isDeclExternC(*this);
 }
 
 bool FunctionDecl::isInExternCContext() const {
@@ -2541,6 +2608,18 @@
     NamedDecl **A = new (getASTContext()) NamedDecl*[NewDecls.size()];
     std::copy(NewDecls.begin(), NewDecls.end(), A);
     DeclsInPrototypeScope = ArrayRef<NamedDecl *>(A, NewDecls.size());
+    // Move declarations introduced in prototype to the function context.
+    for (auto I : NewDecls) {
+      DeclContext *DC = I->getDeclContext();
+      // Forward-declared reference to an enumeration is not added to
+      // declaration scope, so skip declaration that is absent from its
+      // declaration contexts.
+      if (DC->containsDecl(I)) {
+          DC->removeDecl(I);
+          I->setDeclContext(this);
+          addDecl(I);
+      }
+    }
   }
 }
 
@@ -2672,6 +2751,26 @@
   return FoundBody;
 }
 
+SourceRange FunctionDecl::getReturnTypeSourceRange() const {
+  const TypeSourceInfo *TSI = getTypeSourceInfo();
+  if (!TSI)
+    return SourceRange();
+  FunctionTypeLoc FTL =
+      TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
+  if (!FTL)
+    return SourceRange();
+
+  // Skip self-referential return types.
+  const SourceManager &SM = getASTContext().getSourceManager();
+  SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
+  SourceLocation Boundary = getNameInfo().getLocStart();
+  if (RTRange.isInvalid() || Boundary.isInvalid() ||
+      !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
+    return SourceRange();
+
+  return RTRange;
+}
+
 /// \brief For an inline function definition in C, or for a gnu_inline function
 /// in C++, determine whether the definition will be externally visible.
 ///
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 0ac8b73..43d0fca 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -70,7 +70,8 @@
     ImplicitCopyAssignmentHasConstParam(true),
     HasDeclaredCopyConstructorWithConstParam(false),
     HasDeclaredCopyAssignmentWithConstParam(false),
-    IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(),
+    IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0),
+    Bases(), VBases(),
     Definition(D), FirstFriend() {
 }
 
@@ -334,8 +335,10 @@
     addedClassSubobject(BaseClassDecl);
   }
   
-  if (VBases.empty())
+  if (VBases.empty()) {
+    data().IsParsingBaseSpecifiers = false;
     return;
+  }
 
   // Create base specifier for any direct or indirect virtual bases.
   data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
@@ -346,6 +349,8 @@
       addedClassSubobject(Type->getAsCXXRecordDecl());
     data().getVBases()[I] = *VBases[I];
   }
+
+  data().IsParsingBaseSpecifiers = false;
 }
 
 void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 558654d..e5e5130 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -536,6 +536,7 @@
             SimpleInit->printPretty(Out, nullptr, Policy, Indentation);
           else {
             for (unsigned I = 0; I != NumArgs; ++I) {
+              assert(Args[I] != nullptr && "Expected non-null Expr");
               if (isa<CXXDefaultArgExpr>(Args[I]))
                 break;
               
@@ -586,7 +587,8 @@
     } else
       Out << ' ';
 
-    D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation);
+    if (D->getBody())
+      D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation);
     Out << '\n';
   }
 }
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index a69146b..0d1d2a4 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -164,11 +164,11 @@
 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
 RedeclarableTemplateDecl::findSpecializationImpl(
                                  llvm::FoldingSetVector<EntryType> &Specs,
-                                 const TemplateArgument *Args, unsigned NumArgs,
+                                 ArrayRef<TemplateArgument> Args,
                                  void *&InsertPos) {
   typedef SpecEntryTraits<EntryType> SETraits;
   llvm::FoldingSetNodeID ID;
-  EntryType::Profile(ID,Args,NumArgs, getASTContext());
+  EntryType::Profile(ID,Args, getASTContext());
   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
   return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
 }
@@ -263,9 +263,9 @@
 }
 
 FunctionDecl *
-FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
-                                         unsigned NumArgs, void *&InsertPos) {
-  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+                                         void *&InsertPos) {
+  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
 }
 
 void FunctionTemplateDecl::addSpecialization(
@@ -350,9 +350,9 @@
 }
 
 ClassTemplateSpecializationDecl *
-ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
-                                      unsigned NumArgs, void *&InsertPos) {
-  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+                                      void *&InsertPos) {
+  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
 }
 
 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
@@ -370,11 +370,9 @@
 }
 
 ClassTemplatePartialSpecializationDecl *
-ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
-                                             unsigned NumArgs,
+ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
                                              void *&InsertPos) {
-  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
-                                InsertPos);
+  return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
 }
 
 void ClassTemplateDecl::AddPartialSpecialization(
@@ -985,9 +983,9 @@
 }
 
 VarTemplateSpecializationDecl *
-VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
-                                    unsigned NumArgs, void *&InsertPos) {
-  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+                                    void *&InsertPos) {
+  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
 }
 
 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
@@ -1005,10 +1003,9 @@
 }
 
 VarTemplatePartialSpecializationDecl *
-VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
-                                           unsigned NumArgs, void *&InsertPos) {
-  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
-                                InsertPos);
+VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
+                                           void *&InsertPos) {
+  return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
 }
 
 void VarTemplateDecl::AddPartialSpecialization(
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 7e1b2d9..0cc046c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -998,7 +998,7 @@
     TheLexer.LexFromRawLexer(TheTok);
     
     // Use the StringLiteralParser to compute the length of the string in bytes.
-    StringLiteralParser SLP(&TheTok, 1, SM, Features, Target);
+    StringLiteralParser SLP(TheTok, SM, Features, Target);
     unsigned TokNumBytes = SLP.GetStringLength();
     
     // If the byte is in this token, return the location of the byte.
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index c1468cb..3552d65 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1269,11 +1269,29 @@
           LVal.getLValueCallIndex() == 0) &&
          "have call index for global lvalue");
 
-  // Check if this is a thread-local variable.
   if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
     if (const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
+      // Check if this is a thread-local variable.
       if (Var->getTLSKind())
         return false;
+
+      // A dllimport variable never acts like a constant.
+      if (Var->hasAttr<DLLImportAttr>())
+        return false;
+    }
+    if (const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
+      // __declspec(dllimport) must be handled very carefully:
+      // We must never initialize an expression with the thunk in C++.
+      // Doing otherwise would allow the same id-expression to yield
+      // different addresses for the same function in different translation
+      // units.  However, this means that we must dynamically initialize the
+      // expression with the contents of the import address table at runtime.
+      //
+      // The C language has no notion of ODR; furthermore, it has no notion of
+      // dynamic initialization.  This means that we are permitted to
+      // perform initialization with the address of the thunk.
+      if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
+        return false;
     }
   }
 
@@ -2938,6 +2956,7 @@
   if (Object->getType()->isLiteralType(Info.Ctx))
     return EvaluateTemporary(Object, This, Info);
 
+  Info.Diag(Object, diag::note_constexpr_nonliteral) << Object->getType();
   return false;
 }
 
@@ -4647,8 +4666,13 @@
     // Can't look at 'this' when checking a potential constant expression.
     if (Info.checkingPotentialConstantExpression())
       return false;
-    if (!Info.CurrentCall->This)
-      return Error(E);
+    if (!Info.CurrentCall->This) {
+      if (Info.getLangOpts().CPlusPlus11)
+        Info.Diag(E, diag::note_constexpr_this) << E->isImplicit();
+      else
+        Info.Diag(E);
+      return false;
+    }
     Result = *Info.CurrentCall->This;
     return true;
   }
@@ -6029,7 +6053,8 @@
 
   case Builtin::BI__builtin_clz:
   case Builtin::BI__builtin_clzl:
-  case Builtin::BI__builtin_clzll: {
+  case Builtin::BI__builtin_clzll:
+  case Builtin::BI__builtin_clzs: {
     APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
@@ -6044,7 +6069,8 @@
 
   case Builtin::BI__builtin_ctz:
   case Builtin::BI__builtin_ctzl:
-  case Builtin::BI__builtin_ctzll: {
+  case Builtin::BI__builtin_ctzll:
+  case Builtin::BI__builtin_ctzs: {
     APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
@@ -6910,8 +6936,9 @@
 }
 
 CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
-  // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
-  //   result shall be the alignment of the referenced type."
+  // C++ [expr.alignof]p3:
+  //     When alignof is applied to a reference type, the result is the
+  //     alignment of the referenced type.
   if (const ReferenceType *Ref = T->getAs<ReferenceType>())
     T = Ref->getPointeeType();
 
@@ -6930,7 +6957,7 @@
   // alignof decl is always accepted, even if it doesn't make sense: we default
   // to 1 in those cases.
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-    return Info.Ctx.getDeclAlign(DRE->getDecl(), 
+    return Info.Ctx.getDeclAlign(DRE->getDecl(),
                                  /*RefAsPointee*/true);
 
   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
@@ -8702,7 +8729,7 @@
 
 bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
                                     const FunctionDecl *Callee,
-                                    llvm::ArrayRef<const Expr*> Args) const {
+                                    ArrayRef<const Expr*> Args) const {
   Expr::EvalStatus Status;
   EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
 
diff --git a/lib/AST/InheritViz.cpp b/lib/AST/InheritViz.cpp
index 84cc167..eb3020c 100644
--- a/lib/AST/InheritViz.cpp
+++ b/lib/AST/InheritViz.cpp
@@ -139,7 +139,7 @@
 
   int FD;
   SmallString<128> Filename;
-  error_code EC =
+  std::error_code EC =
       sys::fs::createTemporaryFile(Self.getAsString(), "dot", FD, Filename);
   if (EC) {
     llvm::errs() << "Error: " << EC.message() << "\n";
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 58a44b7..1cb6ab5 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2674,7 +2674,6 @@
     llvm_unreachable("cannot mangle opaque value; mangling wrong thing?");
 
   case Expr::InitListExprClass: {
-    // Proposal by Jason Merrill, 2012-01-03
     Out << "il";
     const InitListExpr *InitList = cast<InitListExpr>(E);
     for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
@@ -2739,7 +2738,6 @@
     Out << '_';
     mangleType(New->getAllocatedType());
     if (New->hasInitializer()) {
-      // Proposal by Jason Merrill, 2012-01-03
       if (New->getInitializationStyle() == CXXNewExpr::ListInit)
         Out << "il";
       else
@@ -2825,7 +2823,6 @@
     const CXXConstructExpr *CE = cast<CXXConstructExpr>(E);
     unsigned N = CE->getNumArgs();
 
-    // Proposal by Jason Merrill, 2012-01-03
     if (CE->isListInitialization())
       Out << "tl";
     else
@@ -3425,8 +3422,8 @@
 
     // <seq-id> is encoded in base-36, using digits and upper case letters.
     char Buffer[7]; // log(2**32) / log(36) ~= 7
-    llvm::MutableArrayRef<char> BufferRef(Buffer);
-    llvm::MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
+    MutableArrayRef<char> BufferRef(Buffer);
+    MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
 
     for (; SeqID != 0; SeqID /= 36) {
       unsigned C = SeqID % 36;
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 359e864..6870315 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -93,7 +93,7 @@
 }
 
 MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
-  if (!hasDefinition())
+  if (!hasDefinition() || isParsingBaseSpecifiers())
     return MSInheritanceAttr::Keyword_unspecified_inheritance;
   if (getNumVBases() > 0)
     return MSInheritanceAttr::Keyword_virtual_inheritance;
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index d064b15..e6a6d09 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -193,7 +193,6 @@
 
   typedef llvm::StringMap<unsigned> BackRefMap;
   BackRefMap NameBackReferences;
-  bool UseNameBackReferences;
 
   typedef llvm::DenseMap<void *, unsigned> ArgBackRefMap;
   ArgBackRefMap TypeBackReferences;
@@ -209,14 +208,12 @@
 
   MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
       : Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
-        UseNameBackReferences(true),
         PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
                          64) {}
 
   MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
                           const CXXDestructorDecl *D, CXXDtorType Type)
       : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
-        UseNameBackReferences(true),
         PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
                          64) {}
 
@@ -241,7 +238,6 @@
   void mangleNestedName(const NamedDecl *ND);
 
 private:
-  void disableBackReferences() { UseNameBackReferences = false; }
   void mangleUnqualifiedName(const NamedDecl *ND) {
     mangleUnqualifiedName(ND, ND->getDeclName());
   }
@@ -422,11 +418,11 @@
   //                 ::= <type> <pointee-cvr-qualifiers> # pointers, references
   // Pointers and references are odd. The type of 'int * const foo;' gets
   // mangled as 'QAHA' instead of 'PAHB', for example.
-  TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();
+  SourceRange SR = VD->getSourceRange();
   QualType Ty = VD->getType();
   if (Ty->isPointerType() || Ty->isReferenceType() ||
       Ty->isMemberPointerType()) {
-    mangleType(Ty, TL.getSourceRange(), QMM_Drop);
+    mangleType(Ty, SR, QMM_Drop);
     manglePointerExtQualifiers(
         Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), nullptr);
     if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) {
@@ -444,7 +440,7 @@
     else
       mangleQualifiers(Ty.getQualifiers(), false);
   } else {
-    mangleType(Ty, TL.getSourceRange(), QMM_Drop);
+    mangleType(Ty, SR, QMM_Drop);
     mangleQualifiers(Ty.getLocalQualifiers(), false);
   }
 }
@@ -499,18 +495,9 @@
   //                           ::= $H? <name> <number>
   //                           ::= $I? <name> <number> <number>
   //                           ::= $J? <name> <number> <number> <number>
-  //                           ::= $0A@
 
   MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
 
-  // The null member function pointer is $0A@ in function templates and crashes
-  // MSVC when used in class templates, so we don't know what they really look
-  // like.
-  if (!MD) {
-    Out << "$0A@";
-    return;
-  }
-
   char Code = '\0';
   switch (IM) {
   case MSInheritanceAttr::Keyword_single_inheritance:      Code = '1'; break;
@@ -519,28 +506,38 @@
   case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'J'; break;
   }
 
-  Out << '$' << Code << '?';
-
   // If non-virtual, mangle the name.  If virtual, mangle as a virtual memptr
   // thunk.
   uint64_t NVOffset = 0;
   uint64_t VBTableOffset = 0;
   uint64_t VBPtrOffset = 0;
-  if (MD->isVirtual()) {
-    MicrosoftVTableContext *VTContext =
-        cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
-    const MicrosoftVTableContext::MethodVFTableLocation &ML =
-        VTContext->getMethodVFTableLocation(GlobalDecl(MD));
-    mangleVirtualMemPtrThunk(MD, ML);
-    NVOffset = ML.VFPtrOffset.getQuantity();
-    VBTableOffset = ML.VBTableIndex * 4;
-    if (ML.VBase) {
-      const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
-      VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
+  if (MD) {
+    Out << '$' << Code << '?';
+    if (MD->isVirtual()) {
+      MicrosoftVTableContext *VTContext =
+          cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
+      const MicrosoftVTableContext::MethodVFTableLocation &ML =
+          VTContext->getMethodVFTableLocation(GlobalDecl(MD));
+      mangleVirtualMemPtrThunk(MD, ML);
+      NVOffset = ML.VFPtrOffset.getQuantity();
+      VBTableOffset = ML.VBTableIndex * 4;
+      if (ML.VBase) {
+        const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
+        VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
+      }
+    } else {
+      mangleName(MD);
+      mangleFunctionEncoding(MD);
     }
   } else {
-    mangleName(MD);
-    mangleFunctionEncoding(MD);
+    // Null single inheritance member functions are encoded as a simple nullptr.
+    if (IM == MSInheritanceAttr::Keyword_single_inheritance) {
+      Out << "$0A@";
+      return;
+    }
+    if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance)
+      VBTableOffset = -1;
+    Out << '$' << Code;
   }
 
   if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM))
@@ -601,8 +598,8 @@
     // in the range of ASCII characters 'A' to 'P'.
     // The number 0x123450 would be encoded as 'BCDEFA'
     char EncodedNumberBuffer[sizeof(uint64_t) * 2];
-    llvm::MutableArrayRef<char> BufferRef(EncodedNumberBuffer);
-    llvm::MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
+    MutableArrayRef<char> BufferRef(EncodedNumberBuffer);
+    MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
     for (; Value != 0; Value >>= 4)
       *I++ = 'A' + (Value & 0xf);
     Out.write(I.base(), I - BufferRef.rbegin());
@@ -653,6 +650,7 @@
     // FIXME: Test alias template mangling with MSVC 2013.
     if (!isa<ClassTemplateDecl>(TD)) {
       mangleTemplateInstantiationName(TD, *TemplateArgs);
+      Out << '@';
       return;
     }
 
@@ -667,30 +665,17 @@
     //   type [ -> template-parameters]
     //      \-> namespace[s]
     // What we do is we create a new mangler, mangle the same type (without
-    // a namespace suffix) using the extra mangler with back references
-    // disabled (to avoid infinite recursion) and then use the mangled type
-    // name as a key to check the mangling of different types for aliasing.
+    // a namespace suffix) to a string using the extra mangler and then use 
+    // the mangled type name as a key to check the mangling of different types
+    // for aliasing.
 
-    std::string BackReferenceKey;
-    BackRefMap::iterator Found;
-    if (UseNameBackReferences) {
-      llvm::raw_string_ostream Stream(BackReferenceKey);
-      MicrosoftCXXNameMangler Extra(Context, Stream);
-      Extra.disableBackReferences();
-      Extra.mangleUnqualifiedName(ND, Name);
-      Stream.flush();
+    llvm::SmallString<64> TemplateMangling;
+    llvm::raw_svector_ostream Stream(TemplateMangling);
+    MicrosoftCXXNameMangler Extra(Context, Stream);
+    Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
+    Stream.flush();
 
-      Found = NameBackReferences.find(BackReferenceKey);
-    }
-    if (!UseNameBackReferences || Found == NameBackReferences.end()) {
-      mangleTemplateInstantiationName(TD, *TemplateArgs);
-      if (UseNameBackReferences && NameBackReferences.size() < 10) {
-        size_t Size = NameBackReferences.size();
-        NameBackReferences[BackReferenceKey] = Size;
-      }
-    } else {
-      Out << Found->second;
-    }
+    mangleSourceName(TemplateMangling);
     return;
   }
 
@@ -803,11 +788,8 @@
       break;
 
     case DeclarationName::CXXLiteralOperatorName: {
-      // FIXME: Was this added in VS2010? Does MS even know how to mangle this?
-      DiagnosticsEngine &Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-        "cannot mangle this literal operator yet");
-      Diags.Report(ND->getLocation(), DiagID);
+      Out << "?__K";
+      mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
       break;
     }
 
@@ -1013,14 +995,19 @@
 void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
   // <source name> ::= <identifier> @
   BackRefMap::iterator Found;
-  if (UseNameBackReferences)
+  if (NameBackReferences.size() < 10) {
+    size_t Size = NameBackReferences.size();
+    bool Inserted;
+    std::tie(Found, Inserted) =
+        NameBackReferences.insert(std::make_pair(Name, Size));
+    if (Inserted)
+      Found = NameBackReferences.end();
+  } else {
     Found = NameBackReferences.find(Name);
-  if (!UseNameBackReferences || Found == NameBackReferences.end()) {
+  }
+
+  if (Found == NameBackReferences.end()) {
     Out << Name << '@';
-    if (UseNameBackReferences && NameBackReferences.size() < 10) {
-      size_t Size = NameBackReferences.size();
-      NameBackReferences[Name] = Size;
-    }
   } else {
     Out << Found->second;
   }
@@ -1076,6 +1063,9 @@
     return;
   }
 
+  // Look through no-op casts like template parameter substitutions.
+  E = E->IgnoreParenNoopCasts(Context.getASTContext());
+
   const CXXUuidofExpr *UE = nullptr;
   if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
     if (UO->getOpcode() == UO_AddrOf)
@@ -1113,10 +1103,9 @@
 
 void MicrosoftCXXNameMangler::mangleTemplateArgs(
     const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
-  // <template-args> ::= <template-arg>+ @
+  // <template-args> ::= <template-arg>+
   for (const TemplateArgument &TA : TemplateArgs.asArray())
     mangleTemplateArg(TD, TA);
-  Out << '@';
 }
 
 void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
@@ -1165,23 +1154,31 @@
     QualType T = TA.getNullPtrType();
     if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
       const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
-      if (MPT->isMemberFunctionPointerType())
+      if (MPT->isMemberFunctionPointerType() && isa<ClassTemplateDecl>(TD)) {
         mangleMemberFunctionPointer(RD, nullptr);
-      else
+        return;
+      }
+      if (MPT->isMemberDataPointer()) {
         mangleMemberDataPointer(RD, nullptr);
-    } else {
-      Out << "$0A@";
+        return;
+      }
     }
+    Out << "$0A@";
     break;
   }
   case TemplateArgument::Expression:
     mangleExpression(TA.getAsExpr());
     break;
-  case TemplateArgument::Pack:
-    // Unlike Itanium, there is no character code to indicate an argument pack.
-    for (const TemplateArgument &PA : TA.getPackAsArray())
-      mangleTemplateArg(TD, PA);
+  case TemplateArgument::Pack: {
+    ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
+    if (TemplateArgs.empty()) {
+      Out << "$S";
+    } else {
+      for (const TemplateArgument &PA : TemplateArgs)
+        mangleTemplateArg(TD, PA);
+    }
     break;
+  }
   case TemplateArgument::Template:
     mangleType(cast<TagDecl>(
         TA.getAsTemplate().getAsTemplateDecl()->getTemplatedDecl()));
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index db64f31..caa7cd1 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -2860,11 +2860,20 @@
   assert(RD->getDefinition() && "Cannot get key function for forward decl!");
   RD = cast<CXXRecordDecl>(RD->getDefinition());
 
-  LazyDeclPtr &Entry = KeyFunctions[RD];
-  if (!Entry)
-    Entry = const_cast<CXXMethodDecl*>(computeKeyFunction(*this, RD));
+  // Beware:
+  //  1) computing the key function might trigger deserialization, which might
+  //     invalidate iterators into KeyFunctions
+  //  2) 'get' on the LazyDeclPtr might also trigger deserialization and
+  //     invalidate the LazyDeclPtr within the map itself
+  LazyDeclPtr Entry = KeyFunctions[RD];
+  const Decl *Result =
+      Entry ? Entry.get(getExternalSource()) : computeKeyFunction(*this, RD);
 
-  return cast_or_null<CXXMethodDecl>(Entry.get(getExternalSource()));
+  // Store it back if it changed.
+  if (Entry.isOffset() || Entry.isValid() != bool(Result))
+    KeyFunctions[RD] = const_cast<Decl*>(Result);
+
+  return cast_or_null<CXXMethodDecl>(Result);
 }
 
 void ASTContext::setNonKeyFunction(const CXXMethodDecl *Method) {
@@ -2881,10 +2890,12 @@
   if (I == KeyFunctions.end()) return;
 
   // If it is cached, check whether it's the target method, and if so,
-  // remove it from the cache.
-  if (I->second.get(getExternalSource()) == Method) {
+  // remove it from the cache. Note, the call to 'get' might invalidate
+  // the iterator and the LazyDeclPtr object within the map.
+  LazyDeclPtr Ptr = I->second;
+  if (Ptr.get(getExternalSource()) == Method) {
     // FIXME: remember that we did this for module / chained PCH state?
-    KeyFunctions.erase(I);
+    KeyFunctions.erase(Method->getParent());
   }
 }
 
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 8588dda..9cd3831 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -1168,6 +1168,28 @@
   return new (Mem) OMPFirstprivateClause(N);
 }
 
+OMPLastprivateClause *OMPLastprivateClause::Create(const ASTContext &C,
+                                                   SourceLocation StartLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation EndLoc,
+                                                   ArrayRef<Expr *> VL) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPLastprivateClause *Clause =
+      new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
+                                                        unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPLastprivateClause(N);
+}
+
 OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
@@ -1214,6 +1236,28 @@
   return new (Mem) OMPLinearClause(NumVars);
 }
 
+OMPAlignedClause *
+OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
+                         SourceLocation LParenLoc, SourceLocation ColonLoc,
+                         SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * (VL.size() + 1));
+  OMPAlignedClause *Clause = new (Mem)
+      OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  Clause->setAlignment(A);
+  return Clause;
+}
+
+OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
+                                                unsigned NumVars) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * (NumVars + 1));
+  return new (Mem) OMPAlignedClause(NumVars);
+}
+
 OMPCopyinClause *OMPCopyinClause::Create(const ASTContext &C,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
@@ -1236,12 +1280,55 @@
   return new (Mem) OMPCopyinClause(N);
 }
 
+OMPCopyprivateClause *OMPCopyprivateClause::Create(const ASTContext &C,
+                                                   SourceLocation StartLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation EndLoc,
+                                                   ArrayRef<Expr *> VL) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPCopyprivateClause *Clause =
+      new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
+                                                        unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPCopyprivateClause(N);
+}
+
 void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {
   assert(Clauses.size() == getNumClauses() &&
          "Number of clauses is not the same as the preallocated buffer");
   std::copy(Clauses.begin(), Clauses.end(), getClauses().begin());
 }
 
+OMPReductionClause *OMPReductionClause::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+    SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+    NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPReductionClause *Clause = new (Mem) OMPReductionClause(
+      StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
+                                                    unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPReductionClause(N);
+}
+
 OMPParallelDirective *OMPParallelDirective::Create(
                                               const ASTContext &C,
                                               SourceLocation StartLoc,
@@ -1269,17 +1356,16 @@
   return new (Mem) OMPParallelDirective(NumClauses);
 }
 
-OMPSimdDirective *OMPSimdDirective::Create(const ASTContext &C,
-                                           SourceLocation StartLoc,
-                                           SourceLocation EndLoc,
-                                           ArrayRef<OMPClause *> Clauses,
-                                           Stmt *AssociatedStmt) {
+OMPSimdDirective *
+OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+                         SourceLocation EndLoc, unsigned CollapsedNum,
+                         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
   unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
                                            llvm::alignOf<OMPClause *>());
-  void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
-                         sizeof(Stmt *));
-  OMPSimdDirective *Dir = new (Mem) OMPSimdDirective(StartLoc, EndLoc,
-                                                     1, Clauses.size());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPSimdDirective *Dir = new (Mem)
+      OMPSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
   Dir->setClauses(Clauses);
   Dir->setAssociatedStmt(AssociatedStmt);
   return Dir;
@@ -1291,8 +1377,154 @@
                                                 EmptyShell) {
   unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
                                            llvm::alignOf<OMPClause *>());
-  void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
-                         sizeof(Stmt *));
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
   return new (Mem) OMPSimdDirective(CollapsedNum, NumClauses);
 }
 
+OMPForDirective *
+OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+                        SourceLocation EndLoc, unsigned CollapsedNum,
+                        ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPForDirective *Dir =
+      new (Mem) OMPForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPForDirective *OMPForDirective::CreateEmpty(const ASTContext &C,
+                                              unsigned NumClauses,
+                                              unsigned CollapsedNum,
+                                              EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPForDirective(CollapsedNum, NumClauses);
+}
+
+OMPSectionsDirective *OMPSectionsDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPSectionsDirective *Dir =
+      new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPSectionsDirective *OMPSectionsDirective::CreateEmpty(const ASTContext &C,
+                                                        unsigned NumClauses,
+                                                        EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPSectionsDirective(NumClauses);
+}
+
+OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation EndLoc,
+                                                 Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPSectionDirective *OMPSectionDirective::CreateEmpty(const ASTContext &C,
+                                                      EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  return new (Mem) OMPSectionDirective();
+}
+
+OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C,
+                                               SourceLocation StartLoc,
+                                               SourceLocation EndLoc,
+                                               ArrayRef<OMPClause *> Clauses,
+                                               Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPSingleDirective *Dir =
+      new (Mem) OMPSingleDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C,
+                                                    unsigned NumClauses,
+                                                    EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPSingleDirective(NumClauses);
+}
+
+OMPParallelForDirective *
+OMPParallelForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+                                SourceLocation EndLoc, unsigned CollapsedNum,
+                                ArrayRef<OMPClause *> Clauses,
+                                Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPParallelForDirective *Dir = new (Mem)
+      OMPParallelForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPParallelForDirective *
+OMPParallelForDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                     unsigned CollapsedNum, EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPParallelForDirective(CollapsedNum, NumClauses);
+}
+
+OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPParallelSectionsDirective *Dir =
+      new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPParallelSectionsDirective *
+OMPParallelSectionsDirective::CreateEmpty(const ASTContext &C,
+                                          unsigned NumClauses, EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPParallelSectionsDirective(NumClauses);
+}
+
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 0804d40..1d01e65 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -168,8 +168,10 @@
 }
 
 void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
-  for (const auto *Attr : Node->getAttrs())
+  for (const auto *Attr : Node->getAttrs()) {
     Attr->printPretty(OS, Policy);
+  }
+
   PrintStmt(Node->getSubStmt(), 0);
 }
 
@@ -571,6 +573,11 @@
   OS << "\n";
 }
 
+void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
+  Indent() << "__leave;";
+  if (Policy.IncludeNewlines) OS << "\n";
+}
+
 //===----------------------------------------------------------------------===//
 //  OpenMP clauses printing methods
 //===----------------------------------------------------------------------===//
@@ -626,11 +633,30 @@
      << ")";
 }
 
+void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
+  OS << "schedule("
+     << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
+  if (Node->getChunkSize()) {
+    OS << ", ";
+    Node->getChunkSize()->printPretty(OS, nullptr, Policy);
+  }
+  OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *) {
+  OS << "ordered";
+}
+
+void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
+  OS << "nowait";
+}
+
 template<typename T>
 void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
   for (typename T::varlist_iterator I = Node->varlist_begin(),
                                     E = Node->varlist_end();
          I != E; ++I) {
+    assert(*I && "Expected non-null Stmt");
     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) {
       OS << (I == Node->varlist_begin() ? StartSym : ',');
       cast<NamedDecl>(DRE->getDecl())->printQualifiedName(OS);
@@ -657,6 +683,14 @@
   }
 }
 
+void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "lastprivate";
+    VisitOMPClauseList(Node, '(');
+    OS << ")";
+  }
+}
+
 void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
   if (!Node->varlist_empty()) {
     OS << "shared";
@@ -665,6 +699,28 @@
   }
 }
 
+void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "reduction(";
+    NestedNameSpecifier *QualifierLoc =
+        Node->getQualifierLoc().getNestedNameSpecifier();
+    OverloadedOperatorKind OOK =
+        Node->getNameInfo().getName().getCXXOverloadedOperator();
+    if (QualifierLoc == nullptr && OOK != OO_None) {
+      // Print reduction identifier in C format
+      OS << getOperatorSpelling(OOK);
+    } else {
+      // Use C++ format
+      if (QualifierLoc != nullptr)
+        QualifierLoc->print(OS, Policy);
+      OS << Node->getNameInfo();
+    }
+    OS << ":";
+    VisitOMPClauseList(Node, ' ');
+    OS << ")";
+  }
+}
+
 void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
   if (!Node->varlist_empty()) {
     OS << "linear";
@@ -677,6 +733,18 @@
   }
 }
 
+void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "aligned";
+    VisitOMPClauseList(Node, '(');
+    if (Node->getAlignment() != nullptr) {
+      OS << ": ";
+      Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
+    }
+    OS << ")";
+  }
+}
+
 void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
   if (!Node->varlist_empty()) {
     OS << "copyin";
@@ -685,6 +753,14 @@
   }
 }
 
+void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "copyprivate";
+    VisitOMPClauseList(Node, '(');
+    OS << ")";
+  }
+}
+
 }
 
 //===----------------------------------------------------------------------===//
@@ -719,6 +795,37 @@
   PrintOMPExecutableDirective(Node);
 }
 
+void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
+  Indent() << "#pragma omp for ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
+  Indent() << "#pragma omp sections ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
+  Indent() << "#pragma omp section";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
+  Indent() << "#pragma omp single ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
+  Indent() << "#pragma omp parallel for ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPParallelSectionsDirective(
+    OMPParallelSectionsDirective *Node) {
+  Indent() << "#pragma omp parallel sections ";
+  PrintOMPExecutableDirective(Node);
+}
+
 //===----------------------------------------------------------------------===//
 //  Expr printing methods.
 //===----------------------------------------------------------------------===//
@@ -876,11 +983,10 @@
   // Emit suffixes.  Integer literals are always a builtin integer type.
   switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
   default: llvm_unreachable("Unexpected type for integer literal!");
-  // FIXME: The Short and UShort cases are to handle cases where a short
-  // integeral literal is formed during template instantiation.  They should
-  // be removed when template instantiation no longer needs integer literals.
-  case BuiltinType::Short:
-  case BuiltinType::UShort:
+  case BuiltinType::SChar:     OS << "i8"; break;
+  case BuiltinType::UChar:     OS << "Ui8"; break;
+  case BuiltinType::Short:     OS << "i16"; break;
+  case BuiltinType::UShort:    OS << "Ui16"; break;
   case BuiltinType::Int:       break; // no suffix.
   case BuiltinType::UInt:      OS << 'U'; break;
   case BuiltinType::Long:      OS << 'L'; break;
@@ -1206,10 +1312,12 @@
                       DEnd = Node->designators_end();
        D != DEnd; ++D) {
     if (D->isFieldDesignator()) {
-      if (D->getDotLoc().isInvalid())
-        OS << D->getFieldName()->getName() << ":";
-      else
+      if (D->getDotLoc().isInvalid()) {
+        if (IdentifierInfo *II = D->getFieldName())
+          OS << II->getName() << ":";
+      } else {
         OS << "." << D->getFieldName()->getName();
+      }
     } else {
       OS << "[";
       if (D->isArrayDesignator()) {
@@ -1991,11 +2099,6 @@
                        PrinterHelper *Helper,
                        const PrintingPolicy &Policy,
                        unsigned Indentation) const {
-  if (this == nullptr) {
-    OS << "<NULL>";
-    return;
-  }
-
   StmtPrinter P(OS, Helper, Policy, Indentation);
   P.Visit(const_cast<Stmt*>(this));
 }
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 9cff6d6..db691a9 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -214,6 +214,10 @@
   VisitStmt(S);
 }
 
+void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
+  VisitStmt(S);
+}
+
 void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
   VisitStmt(S);
 }
@@ -288,6 +292,15 @@
 
 void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
 
+void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
+  if (C->getChunkSize())
+    Profiler->VisitStmt(C->getChunkSize());
+}
+
+void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *) {}
+
+void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
+
 template<typename T>
 void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
   for (auto *I : Node->varlists())
@@ -301,16 +314,35 @@
                                          const OMPFirstprivateClause *C) {
   VisitOMPClauseList(C);
 }
+void
+OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
+  VisitOMPClauseList(C);
+}
 void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
   VisitOMPClauseList(C);
 }
+void OMPClauseProfiler::VisitOMPReductionClause(
+                                         const OMPReductionClause *C) {
+  Profiler->VisitNestedNameSpecifier(
+      C->getQualifierLoc().getNestedNameSpecifier());
+  Profiler->VisitName(C->getNameInfo().getName());
+  VisitOMPClauseList(C);
+}
 void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
   VisitOMPClauseList(C);
   Profiler->VisitStmt(C->getStep());
 }
+void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+  VisitOMPClauseList(C);
+  Profiler->VisitStmt(C->getAlignment());
+}
 void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
   VisitOMPClauseList(C);
 }
+void
+OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
+  VisitOMPClauseList(C);
+}
 }
 
 void
@@ -332,6 +364,32 @@
   VisitOMPExecutableDirective(S);
 }
 
+void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void
+StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPParallelSectionsDirective(
+    const OMPParallelSectionsDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
 void StmtProfiler::VisitExpr(const Expr *S) {
   VisitStmt(S);
 }
@@ -619,11 +677,11 @@
 
   case OO_Star:
     if (S->getNumArgs() == 1) {
-      UnaryOp = UO_Minus;
+      UnaryOp = UO_Deref;
       return Stmt::UnaryOperatorClass;
     }
     
-    BinaryOp = BO_Sub;
+    BinaryOp = BO_Mul;
     return Stmt::BinaryOperatorClass;
 
   case OO_Slash:
@@ -768,7 +826,7 @@
   
   llvm_unreachable("Invalid overloaded operator expression");
 }
-                               
+
 
 void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
   if (S->isTypeDependent()) {
@@ -777,7 +835,7 @@
     UnaryOperatorKind UnaryOp = UO_Extension;
     BinaryOperatorKind BinaryOp = BO_Comma;
     Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
-    
+
     ID.AddInteger(SC);
     for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
       Visit(S->getArg(I));
@@ -788,10 +846,10 @@
       ID.AddInteger(BinaryOp);
     else
       assert(SC == Stmt::ArraySubscriptExprClass);
-                    
+
     return;
   }
-  
+
   VisitCallExpr(S);
   ID.AddInteger(S->getOperator());
 }
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index dfb43a0..8e2cea3 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -593,7 +593,8 @@
     OS << " noexcept";
     if (getExceptionSpecType() == EST_ComputedNoexcept) {
       OS << '(';
-      getNoexceptExpr()->printPretty(OS, nullptr, Policy);
+      if (getNoexceptExpr())
+        getNoexceptExpr()->printPretty(OS, nullptr, Policy);
       OS << ')';
     }
   }
@@ -761,7 +762,8 @@
 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
                                         raw_ostream &OS) {
   OS << "typeof ";
-  T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
+  if (T->getUnderlyingExpr())
+    T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
   spaceBeforePlaceHolder(OS);
 }
 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
@@ -777,7 +779,8 @@
 
 void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) { 
   OS << "decltype(";
-  T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
+  if (T->getUnderlyingExpr())
+    T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
   OS << ')';
   spaceBeforePlaceHolder(OS);
 }
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index 6dc3956..fa1127f 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -2446,6 +2446,9 @@
 
   MethodVFTableLocationsTy MethodVFTableLocations;
 
+  /// \brief Does this class have an RTTI component?
+  bool HasRTTIComponent;
+
   /// MethodInfo - Contains information about a method in a vtable.
   /// (Used for computing 'this' pointer adjustment thunks.
   struct MethodInfo {
@@ -2574,6 +2577,13 @@
         MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)),
         WhichVFPtr(*Which),
         Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
+    // Only include the RTTI component if we know that we will provide a
+    // definition of the vftable.
+    HasRTTIComponent = Context.getLangOpts().RTTIData &&
+                       !MostDerivedClass->hasAttr<DLLImportAttr>();
+    if (HasRTTIComponent)
+      Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
+
     LayoutVFTable();
 
     if (Context.getLangOpts().DumpVTableLayouts)
@@ -2915,7 +2925,8 @@
     // it requires return adjustment. Insert the method info for this method.
     unsigned VBIndex =
         LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0;
-    MethodInfo MI(VBIndex, Components.size());
+    MethodInfo MI(VBIndex,
+                  HasRTTIComponent ? Components.size() - 1 : Components.size());
 
     assert(!MethodInfoMap.count(MD) &&
            "Should not have method info for this method yet!");
@@ -3120,9 +3131,8 @@
 }
 
 static bool setsIntersect(const llvm::SmallPtrSet<const CXXRecordDecl *, 4> &A,
-                          const llvm::ArrayRef<const CXXRecordDecl *> &B) {
-  for (llvm::ArrayRef<const CXXRecordDecl *>::iterator I = B.begin(),
-                                                       E = B.end();
+                          const ArrayRef<const CXXRecordDecl *> &B) {
+  for (ArrayRef<const CXXRecordDecl *>::iterator I = B.begin(), E = B.end();
        I != E; ++I) {
     if (A.count(*I))
       return true;
diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h
index 439d3d5..6e144cd 100644
--- a/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -158,10 +158,10 @@
 };
 
 inline bool isRetKindConvertibleTo(
-    llvm::ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
+    ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
     ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
     ast_type_traits::ASTNodeKind *LeastDerivedKind) {
-  for (llvm::ArrayRef<ast_type_traits::ASTNodeKind>::const_iterator
+  for (ArrayRef<ast_type_traits::ASTNodeKind>::const_iterator
            i = RetKinds.begin(),
            e = RetKinds.end();
        i != e; ++i) {
@@ -199,8 +199,8 @@
   /// \param ArgKinds The types of the arguments this matcher takes.
   FixedArgCountMatcherDescriptor(
       MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
-      llvm::ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
-      llvm::ArrayRef<ArgKind> ArgKinds)
+      ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
+      ArrayRef<ArgKind> ArgKinds)
       : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
         RetKinds(RetKinds.begin(), RetKinds.end()),
         ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
@@ -646,7 +646,7 @@
   BuildReturnTypeVector<ReturnType>::build(RetTypes);
   return new FixedArgCountMatcherDescriptor(
       matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
-      MatcherName, RetTypes, llvm::ArrayRef<ArgKind>());
+      MatcherName, RetTypes, None);
 }
 
 /// \brief 1-arg overload
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 87fe043..4bc50a0 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -189,12 +189,14 @@
   REGISTER_MATCHER(hasEitherOperand);
   REGISTER_MATCHER(hasElementType);
   REGISTER_MATCHER(hasFalseExpression);
+  REGISTER_MATCHER(hasGlobalStorage);
   REGISTER_MATCHER(hasImplicitDestinationType);
   REGISTER_MATCHER(hasIncrement);
   REGISTER_MATCHER(hasIndex);
   REGISTER_MATCHER(hasInitializer);
   REGISTER_MATCHER(hasLHS);
   REGISTER_MATCHER(hasLocalQualifiers);
+  REGISTER_MATCHER(hasLocalStorage);
   REGISTER_MATCHER(hasLoopInit);
   REGISTER_MATCHER(hasMethod);
   REGISTER_MATCHER(hasName);
@@ -361,7 +363,7 @@
 }
 
 std::vector<MatcherCompletion> Registry::getCompletions(
-    llvm::ArrayRef<std::pair<MatcherCtor, unsigned> > Context) {
+    ArrayRef<std::pair<MatcherCtor, unsigned> > Context) {
   ASTNodeKind InitialTypes[] = {
     ASTNodeKind::getFromNodeKind<Decl>(),
     ASTNodeKind::getFromNodeKind<QualType>(),
@@ -371,12 +373,12 @@
     ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>(),
     ASTNodeKind::getFromNodeKind<TypeLoc>()
   };
-  llvm::ArrayRef<ASTNodeKind> InitialTypesRef(InitialTypes);
+  ArrayRef<ASTNodeKind> InitialTypesRef(InitialTypes);
 
   // Starting with the above seed of acceptable top-level matcher types, compute
   // the acceptable type set for the argument indicated by each context element.
   std::set<ASTNodeKind> TypeSet(InitialTypesRef.begin(), InitialTypesRef.end());
-  for (llvm::ArrayRef<std::pair<MatcherCtor, unsigned> >::iterator
+  for (ArrayRef<std::pair<MatcherCtor, unsigned> >::iterator
            CtxI = Context.begin(),
            CtxE = Context.end();
        CtxI != CtxE; ++CtxI) {
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 5d2926c..d6361e8 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -3926,7 +3926,8 @@
 
   void VisitIfStmt(IfStmt *I) {
     OS << "if ";
-    I->getCond()->printPretty(OS,Helper,Policy);
+    if (Stmt *C = I->getCond())
+      C->printPretty(OS, Helper, Policy);
   }
 
   // Default case.
@@ -3974,19 +3975,22 @@
   }
 
   void VisitAbstractConditionalOperator(AbstractConditionalOperator* C) {
-    C->getCond()->printPretty(OS, Helper, Policy);
+    if (Stmt *Cond = C->getCond())
+      Cond->printPretty(OS, Helper, Policy);
     OS << " ? ... : ...";
   }
 
   void VisitChooseExpr(ChooseExpr *C) {
     OS << "__builtin_choose_expr( ";
-    C->getCond()->printPretty(OS, Helper, Policy);
+    if (Stmt *Cond = C->getCond())
+      Cond->printPretty(OS, Helper, Policy);
     OS << " )";
   }
 
   void VisitIndirectGotoStmt(IndirectGotoStmt *I) {
     OS << "goto *";
-    I->getTarget()->printPretty(OS, Helper, Policy);
+    if (Stmt *T = I->getTarget())
+      T->printPretty(OS, Helper, Policy);
   }
 
   void VisitBinaryOperator(BinaryOperator* B) {
@@ -3995,7 +3999,8 @@
       return;
     }
 
-    B->getLHS()->printPretty(OS, Helper, Policy);
+    if (B->getLHS())
+      B->getLHS()->printPretty(OS, Helper, Policy);
 
     switch (B->getOpcode()) {
       case BO_LOr:
@@ -4026,7 +4031,8 @@
                        const CFGElement &E) {
   if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
     const Stmt *S = CS->getStmt();
-    
+    assert(S != nullptr && "Expecting non-null Stmt");
+
     // special printing for statement-expressions.
     if (const StmtExpr *SE = dyn_cast<StmtExpr>(S)) {
       const CompoundStmt *Sub = SE->getSubStmt();
@@ -4172,8 +4178,9 @@
       OS << L->getName();
     else if (CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
       OS << "case ";
-      C->getLHS()->printPretty(OS, &Helper,
-                               PrintingPolicy(Helper.getLangOpts()));
+      if (C->getLHS())
+        C->getLHS()->printPretty(OS, &Helper,
+                                 PrintingPolicy(Helper.getLangOpts()));
       if (C->getRHS()) {
         OS << " ... ";
         C->getRHS()->printPretty(OS, &Helper,
@@ -4349,6 +4356,10 @@
   print(llvm::errs(), cfg, LO, ShowColors);
 }
 
+void CFGBlock::dump() const {
+  dump(getParent(), LangOptions(), false);
+}
+
 /// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
 ///   Generally this will only be called from CFG::print.
 void CFGBlock::print(raw_ostream &OS, const CFG* cfg,
diff --git a/lib/Analysis/ThreadSafetyCommon.cpp b/lib/Analysis/ThreadSafetyCommon.cpp
index 91cf849..da88b78 100644
--- a/lib/Analysis/ThreadSafetyCommon.cpp
+++ b/lib/Analysis/ThreadSafetyCommon.cpp
@@ -384,8 +384,7 @@
                                           CallingContext *Ctx) {
   til::SExpr *E0 = translate(E->getBase(), Ctx);
   til::SExpr *E1 = translate(E->getIdx(), Ctx);
-  auto *AA = new (Arena) til::ArrayAdd(E0, E1);
-  return new (Arena) til::ArrayFirst(AA);
+  return new (Arena) til::ArrayIndex(E0, E1);
 }
 
 
@@ -628,7 +627,8 @@
   BlockMap.resize(NBlocks, nullptr);
   // create map from clang blockID to til::BasicBlocks
   for (auto *B : *Cfg) {
-    auto *BB = new (Arena) til::BasicBlock(Arena, 0, B->size());
+    auto *BB = new (Arena) til::BasicBlock(Arena);
+    BB->reserveInstructions(B->size());
     BlockMap[B->getBlockID()] = BB;
   }
   CallCtx.reset(new SExprBuilder::CallingContext(D));
@@ -654,7 +654,7 @@
 void SExprBuilder::enterCFGBlock(const CFGBlock *B) {
   // Intialize TIL basic block and add it to the CFG.
   CurrentBB = lookupBlock(B);
-  CurrentBB->setNumPredecessors(B->pred_size());
+  CurrentBB->reservePredecessors(B->pred_size());
   Scfg->add(CurrentBB);
 
   CurrentBlockInfo = &BBInfo[B->getBlockID()];
@@ -668,6 +668,7 @@
 void SExprBuilder::handlePredecessor(const CFGBlock *Pred) {
   // Compute CurrentLVarMap on entry from ExitMaps of predecessors
 
+  CurrentBB->addPredecessor(BlockMap[Pred->getBlockID()]);
   BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()];
   assert(PredInfo->UnprocessedSuccessors > 0);
 
@@ -724,7 +725,8 @@
   if (N == 1) {
     til::BasicBlock *BB = *It ? lookupBlock(*It) : nullptr;
     // TODO: set index
-    til::SExpr *Tm = new (Arena) til::Goto(BB, 0);
+    unsigned Idx = BB ? BB->findPredecessorIndex(CurrentBB) : 0;
+    til::SExpr *Tm = new (Arena) til::Goto(BB, Idx);
     CurrentBB->setTerminator(Tm);
   }
   else if (N == 2) {
@@ -732,8 +734,9 @@
     til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr;
     ++It;
     til::BasicBlock *BB2 = *It ? lookupBlock(*It) : nullptr;
-    // TODO: set conditional, set index
-    til::SExpr *Tm = new (Arena) til::Branch(C, BB1, BB2);
+    unsigned Idx1 = BB1 ? BB1->findPredecessorIndex(CurrentBB) : 0;
+    unsigned Idx2 = BB2 ? BB2->findPredecessorIndex(CurrentBB) : 0;
+    til::SExpr *Tm = new (Arena) til::Branch(C, BB1, BB2, Idx1, Idx2);
     CurrentBB->setTerminator(Tm);
   }
 }
diff --git a/lib/Analysis/ThreadSafetyLogical.cpp b/lib/Analysis/ThreadSafetyLogical.cpp
index 51a8077..facfa11 100644
--- a/lib/Analysis/ThreadSafetyLogical.cpp
+++ b/lib/Analysis/ThreadSafetyLogical.cpp
@@ -1,112 +1,112 @@
-//===- ThreadSafetyLogical.cpp ---------------------------------*- C++ --*-===//

-//

-//                     The LLVM Compiler Infrastructure

-//

-// This file is distributed under the University of Illinois Open Source

-// License. See LICENSE.TXT for details.

-//

-//===----------------------------------------------------------------------===//

-// This file defines a representation for logical expressions with SExpr leaves

-// that are used as part of fact-checking capability expressions.

-//===----------------------------------------------------------------------===//

-

-#include "clang/Analysis/Analyses/ThreadSafetyLogical.h"

-

-using namespace llvm;

-using namespace clang::threadSafety::lexpr;

-

-// Implication.  We implement De Morgan's Laws by maintaining LNeg and RNeg

-// to keep track of whether LHS and RHS are negated.

-static bool implies(const LExpr *LHS, bool LNeg, const LExpr *RHS, bool RNeg) {

-  // In comments below, we write => for implication.

-

-  // Calculates the logical AND implication operator.

-  const auto LeftAndOperator = [=](const BinOp *A) {

-    return implies(A->left(), LNeg, RHS, RNeg) &&

-           implies(A->right(), LNeg, RHS, RNeg);

-  };

-  const auto RightAndOperator = [=](const BinOp *A) {

-    return implies(LHS, LNeg, A->left(), RNeg) &&

-           implies(LHS, LNeg, A->right(), RNeg);

-  };

-

-  // Calculates the logical OR implication operator.

-  const auto LeftOrOperator = [=](const BinOp *A) {

-    return implies(A->left(), LNeg, RHS, RNeg) ||

-           implies(A->right(), LNeg, RHS, RNeg);

-  };

-  const auto RightOrOperator = [=](const BinOp *A) {

-    return implies(LHS, LNeg, A->left(), RNeg) ||

-           implies(LHS, LNeg, A->right(), RNeg);

-  };

-

-  // Recurse on right.

-  switch (RHS->kind()) {

-  case LExpr::And:

-    // When performing right recursion:

-    //   C => A & B  [if]  C => A and C => B

-    // When performing right recursion (negated):

-    //   C => !(A & B)  [if]  C => !A | !B  [===]  C => !A or C => !B

-    return RNeg ? RightOrOperator(cast<And>(RHS))

-                : RightAndOperator(cast<And>(RHS));

-  case LExpr::Or:

-    // When performing right recursion:

-    //   C => (A | B)  [if]  C => A or C => B

-    // When performing right recursion (negated):

-    //   C => !(A | B)  [if]  C => !A & !B  [===]  C => !A and C => !B

-    return RNeg ? RightAndOperator(cast<Or>(RHS))

-                : RightOrOperator(cast<Or>(RHS));

-  case LExpr::Not:

-    // Note that C => !A is very different from !(C => A). It would be incorrect

-    // to return !implies(LHS, RHS).

-    return implies(LHS, LNeg, cast<Not>(RHS)->exp(), !RNeg);

-  case LExpr::Terminal:

-    // After reaching the terminal, it's time to recurse on the left.

-    break;

-  }

-

-  // RHS is now a terminal.  Recurse on Left.

-  switch (LHS->kind()) {

-  case LExpr::And:

-    // When performing left recursion:

-    //   A & B => C  [if]  A => C or B => C

-    // When performing left recursion (negated):

-    //   !(A & B) => C  [if]  !A | !B => C  [===]  !A => C and !B => C

-    return LNeg ? LeftAndOperator(cast<And>(LHS))

-                : LeftOrOperator(cast<And>(LHS));

-  case LExpr::Or:

-    // When performing left recursion:

-    //   A | B => C  [if]  A => C and B => C

-    // When performing left recursion (negated):

-    //   !(A | B) => C  [if]  !A & !B => C  [===]  !A => C or !B => C

-    return LNeg ? LeftOrOperator(cast<Or>(LHS))

-                : LeftAndOperator(cast<Or>(LHS));

-  case LExpr::Not:

-    // Note that A => !C is very different from !(A => C). It would be incorrect

-    // to return !implies(LHS, RHS).

-    return implies(cast<Not>(LHS)->exp(), !LNeg, RHS, RNeg);

-  case LExpr::Terminal:

-    // After reaching the terminal, it's time to perform identity comparisons.

-    break;

-  }

-

-  // A => A

-  // !A => !A

-  if (LNeg != RNeg)

-    return false;

-

-  // FIXME -- this should compare SExprs for equality, not pointer equality.

-  return cast<Terminal>(LHS)->expr() == cast<Terminal>(RHS)->expr();

-}

-

-namespace clang {

-namespace threadSafety {

-namespace lexpr {

-

-bool implies(const LExpr *LHS, const LExpr *RHS) {

-  // Start out by assuming that LHS and RHS are not negated.

-  return ::implies(LHS, false, RHS, false);

-}

-}

-}

-}

+//===- ThreadSafetyLogical.cpp ---------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file defines a representation for logical expressions with SExpr leaves
+// that are used as part of fact-checking capability expressions.
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/ThreadSafetyLogical.h"
+
+using namespace llvm;
+using namespace clang::threadSafety::lexpr;
+
+// Implication.  We implement De Morgan's Laws by maintaining LNeg and RNeg
+// to keep track of whether LHS and RHS are negated.
+static bool implies(const LExpr *LHS, bool LNeg, const LExpr *RHS, bool RNeg) {
+  // In comments below, we write => for implication.
+
+  // Calculates the logical AND implication operator.
+  const auto LeftAndOperator = [=](const BinOp *A) {
+    return implies(A->left(), LNeg, RHS, RNeg) &&
+           implies(A->right(), LNeg, RHS, RNeg);
+  };
+  const auto RightAndOperator = [=](const BinOp *A) {
+    return implies(LHS, LNeg, A->left(), RNeg) &&
+           implies(LHS, LNeg, A->right(), RNeg);
+  };
+
+  // Calculates the logical OR implication operator.
+  const auto LeftOrOperator = [=](const BinOp *A) {
+    return implies(A->left(), LNeg, RHS, RNeg) ||
+           implies(A->right(), LNeg, RHS, RNeg);
+  };
+  const auto RightOrOperator = [=](const BinOp *A) {
+    return implies(LHS, LNeg, A->left(), RNeg) ||
+           implies(LHS, LNeg, A->right(), RNeg);
+  };
+
+  // Recurse on right.
+  switch (RHS->kind()) {
+  case LExpr::And:
+    // When performing right recursion:
+    //   C => A & B  [if]  C => A and C => B
+    // When performing right recursion (negated):
+    //   C => !(A & B)  [if]  C => !A | !B  [===]  C => !A or C => !B
+    return RNeg ? RightOrOperator(cast<And>(RHS))
+                : RightAndOperator(cast<And>(RHS));
+  case LExpr::Or:
+    // When performing right recursion:
+    //   C => (A | B)  [if]  C => A or C => B
+    // When performing right recursion (negated):
+    //   C => !(A | B)  [if]  C => !A & !B  [===]  C => !A and C => !B
+    return RNeg ? RightAndOperator(cast<Or>(RHS))
+                : RightOrOperator(cast<Or>(RHS));
+  case LExpr::Not:
+    // Note that C => !A is very different from !(C => A). It would be incorrect
+    // to return !implies(LHS, RHS).
+    return implies(LHS, LNeg, cast<Not>(RHS)->exp(), !RNeg);
+  case LExpr::Terminal:
+    // After reaching the terminal, it's time to recurse on the left.
+    break;
+  }
+
+  // RHS is now a terminal.  Recurse on Left.
+  switch (LHS->kind()) {
+  case LExpr::And:
+    // When performing left recursion:
+    //   A & B => C  [if]  A => C or B => C
+    // When performing left recursion (negated):
+    //   !(A & B) => C  [if]  !A | !B => C  [===]  !A => C and !B => C
+    return LNeg ? LeftAndOperator(cast<And>(LHS))
+                : LeftOrOperator(cast<And>(LHS));
+  case LExpr::Or:
+    // When performing left recursion:
+    //   A | B => C  [if]  A => C and B => C
+    // When performing left recursion (negated):
+    //   !(A | B) => C  [if]  !A & !B => C  [===]  !A => C or !B => C
+    return LNeg ? LeftOrOperator(cast<Or>(LHS))
+                : LeftAndOperator(cast<Or>(LHS));
+  case LExpr::Not:
+    // Note that A => !C is very different from !(A => C). It would be incorrect
+    // to return !implies(LHS, RHS).
+    return implies(cast<Not>(LHS)->exp(), !LNeg, RHS, RNeg);
+  case LExpr::Terminal:
+    // After reaching the terminal, it's time to perform identity comparisons.
+    break;
+  }
+
+  // A => A
+  // !A => !A
+  if (LNeg != RNeg)
+    return false;
+
+  // FIXME -- this should compare SExprs for equality, not pointer equality.
+  return cast<Terminal>(LHS)->expr() == cast<Terminal>(RHS)->expr();
+}
+
+namespace clang {
+namespace threadSafety {
+namespace lexpr {
+
+bool implies(const LExpr *LHS, const LExpr *RHS) {
+  // Start out by assuming that LHS and RHS are not negated.
+  return ::implies(LHS, false, RHS, false);
+}
+}
+}
+}
diff --git a/lib/Analysis/ThreadSafetyTIL.cpp b/lib/Analysis/ThreadSafetyTIL.cpp
index f4da8d4..f67cbb9 100644
--- a/lib/Analysis/ThreadSafetyTIL.cpp
+++ b/lib/Analysis/ThreadSafetyTIL.cpp
@@ -48,6 +48,46 @@
 }
 
 
+unsigned BasicBlock::addPredecessor(BasicBlock *Pred) {
+  unsigned Idx = Predecessors.size();
+  Predecessors.reserveCheck(1, Arena);
+  Predecessors.push_back(Pred);
+  for (Variable *V : Args) {
+    if (Phi* Ph = dyn_cast<Phi>(V->definition())) {
+      Ph->values().reserveCheck(1, Arena);
+      Ph->values().push_back(nullptr);
+    }
+  }
+  return Idx;
+}
+
+void BasicBlock::reservePredecessors(unsigned NumPreds) {
+  Predecessors.reserve(NumPreds, Arena);
+  for (Variable *V : Args) {
+    if (Phi* Ph = dyn_cast<Phi>(V->definition())) {
+      Ph->values().reserve(NumPreds, Arena);
+    }
+  }
+}
+
+void BasicBlock::renumberVars() {
+  unsigned VID = 0;
+  for (Variable *V : Args) {
+    V->setID(BlockID, VID++);
+  }
+  for (Variable *V : Instrs) {
+    V->setID(BlockID, VID++);
+  }
+}
+
+void SCFG::renumberVars() {
+  for (BasicBlock *B : Blocks) {
+    B->renumberVars();
+  }
+}
+
+
+
 
 // If E is a variable, then trace back through any aliases or redundant
 // Phi nodes to find the canonical definition.
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
index 4b8a59c..f5c786a 100644
--- a/lib/Analysis/UninitializedValues.cpp
+++ b/lib/Analysis/UninitializedValues.cpp
@@ -34,7 +34,7 @@
 
 static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) {
   if (vd->isLocalVarDecl() && !vd->hasGlobalStorage() &&
-      !vd->isExceptionVariable() &&
+      !vd->isExceptionVariable() && !vd->isInitCapture() &&
       vd->getDeclContext() == dc) {
     QualType ty = vd->getType();
     return ty->isScalarType() || ty->isVectorType();
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp
index 6c78dc3..8efcac6 100644
--- a/lib/Basic/Builtins.cpp
+++ b/lib/Basic/Builtins.cpp
@@ -76,7 +76,7 @@
 
   // Step #2: Register target-specific builtins.
   for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
-    if (!LangOpts.NoBuiltin || !strchr(TSRecords[i].Attributes, 'f'))
+    if (BuiltinIsSupported(TSRecords[i], LangOpts))
       Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
 }
 
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 13d2524..f784fe7 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -24,15 +24,13 @@
 using namespace clang;
 
 static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
-                               const char *Modifier, unsigned ML,
-                               const char *Argument, unsigned ArgLen,
-                               const DiagnosticsEngine::ArgumentValue *PrevArgs,
-                               unsigned NumPrevArgs,
-                               SmallVectorImpl<char> &Output,
-                               void *Cookie,
-                               ArrayRef<intptr_t> QualTypeVals) {
-  const char *Str = "<can't format argument>";
-  Output.append(Str, Str+strlen(Str));
+                            StringRef Modifier, StringRef Argument,
+                            ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+                            SmallVectorImpl<char> &Output,
+                            void *Cookie,
+                            ArrayRef<intptr_t> QualTypeVals) {
+  StringRef Str = "<can't format argument>";
+  Output.append(Str.begin(), Str.end());
 }
 
 
@@ -56,7 +54,7 @@
   PrintTemplateTree = false;
   ShowColors = false;
   ShowOverloads = Ovl_All;
-  ExtBehavior = Ext_Ignore;
+  ExtBehavior = diag::Severity::Ignored;
 
   ErrorLimit = 0;
   TemplateBacktraceLimit = 0;
@@ -162,12 +160,12 @@
   return Pos;
 }
 
-void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
-                                             SourceLocation L) {
+void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
+                                    SourceLocation L) {
   assert(Diag < diag::DIAG_UPPER_LIMIT &&
          "Can only map builtin diagnostics");
   assert((Diags->isBuiltinWarningOrExtension(Diag) ||
-          (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
+          (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
          "Cannot map errors into warnings!");
   assert(!DiagStatePoints.empty());
   assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
@@ -175,17 +173,17 @@
   FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc();
   FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
   // Don't allow a mapping to a warning override an error/fatal mapping.
-  if (Map == diag::MAP_WARNING) {
-    DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
-    if (Info.getMapping() == diag::MAP_ERROR ||
-        Info.getMapping() == diag::MAP_FATAL)
-      Map = Info.getMapping();
+  if (Map == diag::Severity::Warning) {
+    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
+    if (Info.getSeverity() == diag::Severity::Error ||
+        Info.getSeverity() == diag::Severity::Fatal)
+      Map = Info.getSeverity();
   }
-  DiagnosticMappingInfo MappingInfo = makeMappingInfo(Map, L);
+  DiagnosticMapping Mapping = makeUserMapping(Map, L);
 
   // Common case; setting all the diagnostics of a group in one place.
   if (Loc.isInvalid() || Loc == LastStateChangePos) {
-    GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+    GetCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
@@ -198,7 +196,7 @@
     // the new state became active.
     DiagStates.push_back(*GetCurDiagState());
     PushDiagStatePoint(&DiagStates.back(), Loc);
-    GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+    GetCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
@@ -211,12 +209,12 @@
   // Update all diagnostic states that are active after the given location.
   for (DiagStatePointsTy::iterator
          I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
-    GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+    GetCurDiagState()->setMapping(Diag, Mapping);
   }
 
   // If the location corresponds to an existing point, just update its state.
   if (Pos->Loc == Loc) {
-    GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+    GetCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
@@ -225,14 +223,13 @@
   assert(Pos->Loc.isBeforeInTranslationUnitThan(Loc));
   DiagStates.push_back(*Pos->State);
   DiagState *NewState = &DiagStates.back();
-  GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+  GetCurDiagState()->setMapping(Diag, Mapping);
   DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
                                                FullSourceLoc(Loc, *SourceMgr)));
 }
 
-bool DiagnosticsEngine::setDiagnosticGroupMapping(
-  StringRef Group, diag::Mapping Map, SourceLocation Loc)
-{
+bool DiagnosticsEngine::setSeverityForGroup(StringRef Group, diag::Severity Map,
+                                            SourceLocation Loc) {
   // Get the diagnostics in this group.
   SmallVector<diag::kind, 8> GroupDiags;
   if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
@@ -240,7 +237,7 @@
 
   // Set the mapping.
   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i)
-    setDiagnosticMapping(GroupDiags[i], Map, Loc);
+    setSeverity(GroupDiags[i], Map, Loc);
 
   return false;
 }
@@ -250,7 +247,7 @@
   // If we are enabling this feature, just set the diagnostic mappings to map to
   // errors.
   if (Enabled)
-    return setDiagnosticGroupMapping(Group, diag::MAP_ERROR);
+    return setSeverityForGroup(Group, diag::Severity::Error);
 
   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
   // potentially downgrade anything already mapped to be a warning.
@@ -262,12 +259,11 @@
 
   // Perform the mapping change.
   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
-    DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
-      GroupDiags[i]);
+    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(GroupDiags[i]);
 
-    if (Info.getMapping() == diag::MAP_ERROR ||
-        Info.getMapping() == diag::MAP_FATAL)
-      Info.setMapping(diag::MAP_WARNING);
+    if (Info.getSeverity() == diag::Severity::Error ||
+        Info.getSeverity() == diag::Severity::Fatal)
+      Info.setSeverity(diag::Severity::Warning);
 
     Info.setNoWarningAsError(true);
   }
@@ -280,7 +276,7 @@
   // If we are enabling this feature, just set the diagnostic mappings to map to
   // fatal errors.
   if (Enabled)
-    return setDiagnosticGroupMapping(Group, diag::MAP_FATAL);
+    return setSeverityForGroup(Group, diag::Severity::Fatal);
 
   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
   // potentially downgrade anything already mapped to be an error.
@@ -292,11 +288,10 @@
 
   // Perform the mapping change.
   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
-    DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
-      GroupDiags[i]);
+    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(GroupDiags[i]);
 
-    if (Info.getMapping() == diag::MAP_FATAL)
-      Info.setMapping(diag::MAP_ERROR);
+    if (Info.getSeverity() == diag::Severity::Fatal)
+      Info.setSeverity(diag::Severity::Error);
 
     Info.setNoErrorAsFatal(true);
   }
@@ -304,8 +299,8 @@
   return false;
 }
 
-void DiagnosticsEngine::setMappingToAllDiagnostics(diag::Mapping Map,
-                                                   SourceLocation Loc) {
+void DiagnosticsEngine::setSeverityForAll(diag::Severity Map,
+                                          SourceLocation Loc) {
   // Get all the diagnostics.
   SmallVector<diag::kind, 64> AllDiags;
   Diags->getAllDiagnostics(AllDiags);
@@ -313,7 +308,7 @@
   // Set the mapping.
   for (unsigned i = 0, e = AllDiags.size(); i != e; ++i)
     if (Diags->isBuiltinWarningOrExtension(AllDiags[i]))
-      setDiagnosticMapping(AllDiags[i], Map, Loc);
+      setSeverity(AllDiags[i], Map, Loc);
 }
 
 void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
@@ -829,9 +824,9 @@
     case DiagnosticsEngine::ak_declcontext:
     case DiagnosticsEngine::ak_attr:
       getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
-                                     Modifier, ModifierLen,
-                                     Argument, ArgumentLen,
-                                     FormattedArgs.data(), FormattedArgs.size(),
+                                     StringRef(Modifier, ModifierLen),
+                                     StringRef(Argument, ArgumentLen),
+                                     FormattedArgs,
                                      OutStr, QualTypeVals);
       break;
     case DiagnosticsEngine::ak_qualtype_pair:
@@ -853,10 +848,9 @@
         TDT.PrintFromType = true;
         TDT.PrintTree = true;
         getDiags()->ConvertArgToString(Kind, val,
-                                       Modifier, ModifierLen,
-                                       Argument, ArgumentLen,
-                                       FormattedArgs.data(),
-                                       FormattedArgs.size(),
+                                       StringRef(Modifier, ModifierLen),
+                                       StringRef(Argument, ArgumentLen),
+                                       FormattedArgs,
                                        Tree, QualTypeVals);
         // If there is no tree information, fall back to regular printing.
         if (!Tree.empty()) {
@@ -877,9 +871,9 @@
       TDT.PrintTree = false;
       TDT.PrintFromType = true;
       getDiags()->ConvertArgToString(Kind, val,
-                                     Modifier, ModifierLen,
-                                     Argument, ArgumentLen,
-                                     FormattedArgs.data(), FormattedArgs.size(),
+                                     StringRef(Modifier, ModifierLen),
+                                     StringRef(Argument, ArgumentLen),
+                                     FormattedArgs,
                                      OutStr, QualTypeVals);
       if (!TDT.TemplateDiffUsed)
         FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
@@ -891,9 +885,9 @@
       // Append second type
       TDT.PrintFromType = false;
       getDiags()->ConvertArgToString(Kind, val,
-                                     Modifier, ModifierLen,
-                                     Argument, ArgumentLen,
-                                     FormattedArgs.data(), FormattedArgs.size(),
+                                     StringRef(Modifier, ModifierLen),
+                                     StringRef(Argument, ArgumentLen),
+                                     FormattedArgs,
                                      OutStr, QualTypeVals);
       if (!TDT.TemplateDiffUsed)
         FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 4779859..0bb0b9f 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -38,7 +38,7 @@
 
 struct StaticDiagInfoRec {
   uint16_t DiagID;
-  unsigned Mapping : 3;
+  unsigned DefaultSeverity : 3;
   unsigned Class : 3;
   unsigned SFINAE : 2;
   unsigned WarnNoWerror : 1;
@@ -66,12 +66,13 @@
 } // namespace anonymous
 
 static const StaticDiagInfoRec StaticDiagInfo[] = {
-#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,               \
-             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY)            \
-  { diag::ENUM, DEFAULT_MAPPING, CLASS,                           \
-    DiagnosticIDs::SFINAE,                                        \
-    NOWERROR, SHOWINSYSHEADER, CATEGORY, GROUP,                   \
-    STR_SIZE(DESC, uint16_t), DESC },
+#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR,     \
+             SHOWINSYSHEADER, CATEGORY)                                        \
+  {                                                                            \
+    diag::ENUM, DEFAULT_SEVERITY, CLASS, DiagnosticIDs::SFINAE, NOWERROR,      \
+        SHOWINSYSHEADER, CATEGORY, GROUP, STR_SIZE(DESC, uint16_t), DESC       \
+  }                                                                            \
+  ,
 #include "clang/Basic/DiagnosticCommonKinds.inc"
 #include "clang/Basic/DiagnosticDriverKinds.inc"
 #include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -152,24 +153,18 @@
   return Found;
 }
 
-static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) {
-  DiagnosticMappingInfo Info = DiagnosticMappingInfo::Make(
-    diag::MAP_FATAL, /*IsUser=*/false, /*IsPragma=*/false);
+static DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) {
+  DiagnosticMapping Info = DiagnosticMapping::Make(
+      diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false);
 
   if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) {
-    Info.setMapping((diag::Mapping) StaticInfo->Mapping);
+    Info.setSeverity((diag::Severity)StaticInfo->DefaultSeverity);
 
     if (StaticInfo->WarnNoWerror) {
-      assert(Info.getMapping() == diag::MAP_WARNING &&
+      assert(Info.getSeverity() == diag::Severity::Warning &&
              "Unexpected mapping with no-Werror bit!");
       Info.setNoWarningAsError(true);
     }
-
-    if (StaticInfo->WarnShowInSystemHeader) {
-      assert(Info.getMapping() == diag::MAP_WARNING &&
-             "Unexpected mapping with show-in-system-header bit!");
-      Info.setShowInSystemHeader(true);
-    }
   }
 
   return Info;
@@ -198,15 +193,14 @@
 // Unfortunately, the split between DiagnosticIDs and Diagnostic is not
 // particularly clean, but for now we just implement this method here so we can
 // access GetDefaultDiagMapping.
-DiagnosticMappingInfo &DiagnosticsEngine::DiagState::getOrAddMappingInfo(
-  diag::kind Diag)
-{
-  std::pair<iterator, bool> Result = DiagMap.insert(
-    std::make_pair(Diag, DiagnosticMappingInfo()));
+DiagnosticMapping &
+DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
+  std::pair<iterator, bool> Result =
+      DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
 
   // Initialize the entry if we added it.
   if (Result.second)
-    Result.first->second = GetDefaultDiagMappingInfo(Diag);
+    Result.first->second = GetDefaultDiagMapping(Diag);
 
   return Result.first->second;
 }
@@ -346,9 +340,9 @@
   if (DiagID >= diag::DIAG_UPPER_LIMIT ||
       getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
     return false;
-  
+
   EnabledByDefault =
-    GetDefaultDiagMappingInfo(DiagID).getMapping() != diag::MAP_IGNORE;
+      GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored;
   return true;
 }
 
@@ -356,12 +350,7 @@
   if (DiagID >= diag::DIAG_UPPER_LIMIT)
     return false;
 
-  return GetDefaultDiagMappingInfo(DiagID).getMapping() == diag::MAP_ERROR;
-}
-
-bool DiagnosticIDs::isRemark(unsigned DiagID) {
-  return DiagID < diag::DIAG_UPPER_LIMIT &&
-         getBuiltinDiagClass(DiagID) == CLASS_REMARK;
+  return GetDefaultDiagMapping(DiagID).getSeverity() == diag::Severity::Error;
 }
 
 /// getDescription - Given a diagnostic ID, return a description of the
@@ -372,6 +361,22 @@
   return CustomDiagInfo->getDescription(DiagID);
 }
 
+static DiagnosticIDs::Level toLevel(diag::Severity SV) {
+  switch (SV) {
+  case diag::Severity::Ignored:
+    return DiagnosticIDs::Ignored;
+  case diag::Severity::Remark:
+    return DiagnosticIDs::Remark;
+  case diag::Severity::Warning:
+    return DiagnosticIDs::Warning;
+  case diag::Severity::Error:
+    return DiagnosticIDs::Error;
+  case diag::Severity::Fatal:
+    return DiagnosticIDs::Fatal;
+  }
+  llvm_unreachable("unexpected severity");
+}
+
 /// getDiagnosticLevel - Based on the way the client configured the
 /// DiagnosticsEngine object, classify the specified diagnostic ID into a Level,
 /// by consumable the DiagnosticClient.
@@ -384,7 +389,7 @@
 
   unsigned DiagClass = getBuiltinDiagClass(DiagID);
   if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note;
-  return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag);
+  return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag));
 }
 
 /// \brief Based on the way the client configured the Diagnostic
@@ -393,49 +398,37 @@
 ///
 /// \param Loc The source location we are interested in finding out the
 /// diagnostic state. Can be null in order to query the latest state.
-DiagnosticIDs::Level
-DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
-                                  SourceLocation Loc,
-                                  const DiagnosticsEngine &Diag) const {
+diag::Severity
+DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
+                                     const DiagnosticsEngine &Diag) const {
+  assert(getBuiltinDiagClass(DiagID) != CLASS_NOTE);
+
   // Specific non-error diagnostics may be mapped to various levels from ignored
   // to error.  Errors can only be mapped to fatal.
-  DiagnosticIDs::Level Result = DiagnosticIDs::Fatal;
+  diag::Severity Result = diag::Severity::Fatal;
 
   DiagnosticsEngine::DiagStatePointsTy::iterator
     Pos = Diag.GetDiagStatePointForLoc(Loc);
   DiagnosticsEngine::DiagState *State = Pos->State;
 
   // Get the mapping information, or compute it lazily.
-  DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo(
-    (diag::kind)DiagID);
+  DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
 
-  switch (MappingInfo.getMapping()) {
-  case diag::MAP_IGNORE:
-    Result = DiagnosticIDs::Ignored;
-    break;
-  case diag::MAP_REMARK:
-    Result = DiagnosticIDs::Remark;
-    break;
-  case diag::MAP_WARNING:
-    Result = DiagnosticIDs::Warning;
-    break;
-  case diag::MAP_ERROR:
-    Result = DiagnosticIDs::Error;
-    break;
-  case diag::MAP_FATAL:
-    Result = DiagnosticIDs::Fatal;
-    break;
-  }
+  // TODO: Can a null severity really get here?
+  if (Mapping.getSeverity() != diag::Severity())
+    Result = Mapping.getSeverity();
 
   // Upgrade ignored diagnostics if -Weverything is enabled.
-  if (Diag.EnableAllWarnings && Result == DiagnosticIDs::Ignored &&
-      !MappingInfo.isUser())
-    Result = DiagnosticIDs::Warning;
+  if (Diag.EnableAllWarnings && Result == diag::Severity::Ignored &&
+      !Mapping.isUser())
+    Result = diag::Severity::Warning;
 
   // Diagnostics of class REMARK are either printed as remarks or in case they
   // have been added to -Werror they are printed as errors.
-  if (DiagClass == CLASS_REMARK && Result == DiagnosticIDs::Warning)
-    Result = DiagnosticIDs::Remark;
+  // FIXME: Disregarding user-requested remark mappings like this is bogus.
+  if (Result == diag::Severity::Warning &&
+      getBuiltinDiagClass(DiagID) == CLASS_REMARK)
+    Result = diag::Severity::Remark;
 
   // Ignore -pedantic diagnostics inside __extension__ blocks.
   // (The diagnostics controlled by -pedantic are the extension diagnostics
@@ -443,62 +436,46 @@
   bool EnabledByDefault = false;
   bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
   if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault)
-    return DiagnosticIDs::Ignored;
+    return diag::Severity::Ignored;
 
   // For extension diagnostics that haven't been explicitly mapped, check if we
   // should upgrade the diagnostic.
-  if (IsExtensionDiag && !MappingInfo.isUser()) {
-    switch (Diag.ExtBehavior) {
-    case DiagnosticsEngine::Ext_Ignore:
-      break; 
-    case DiagnosticsEngine::Ext_Warn:
-      // Upgrade ignored diagnostics to warnings.
-      if (Result == DiagnosticIDs::Ignored)
-        Result = DiagnosticIDs::Warning;
-      break;
-    case DiagnosticsEngine::Ext_Error:
-      // Upgrade ignored or warning diagnostics to errors.
-      if (Result == DiagnosticIDs::Ignored || Result == DiagnosticIDs::Warning)
-        Result = DiagnosticIDs::Error;
-      break;
-    }
-  }
+  if (IsExtensionDiag && !Mapping.isUser())
+    Result = std::max(Result, Diag.ExtBehavior);
 
   // At this point, ignored errors can no longer be upgraded.
-  if (Result == DiagnosticIDs::Ignored)
+  if (Result == diag::Severity::Ignored)
     return Result;
 
   // Honor -w, which is lower in priority than pedantic-errors, but higher than
   // -Werror.
-  if (Result == DiagnosticIDs::Warning && Diag.IgnoreAllWarnings)
-    return DiagnosticIDs::Ignored;
+  if (Result == diag::Severity::Warning && Diag.IgnoreAllWarnings)
+    return diag::Severity::Ignored;
 
   // If -Werror is enabled, map warnings to errors unless explicitly disabled.
-  if (Result == DiagnosticIDs::Warning) {
-    if (Diag.WarningsAsErrors && !MappingInfo.hasNoWarningAsError())
-      Result = DiagnosticIDs::Error;
+  if (Result == diag::Severity::Warning) {
+    if (Diag.WarningsAsErrors && !Mapping.hasNoWarningAsError())
+      Result = diag::Severity::Error;
   }
 
   // If -Wfatal-errors is enabled, map errors to fatal unless explicity
   // disabled.
-  if (Result == DiagnosticIDs::Error) {
-    if (Diag.ErrorsAsFatal && !MappingInfo.hasNoErrorAsFatal())
-      Result = DiagnosticIDs::Fatal;
+  if (Result == diag::Severity::Error) {
+    if (Diag.ErrorsAsFatal && !Mapping.hasNoErrorAsFatal())
+      Result = diag::Severity::Fatal;
   }
 
+  // Custom diagnostics always are emitted in system headers.
+  bool ShowInSystemHeader =
+      !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader;
+
   // If we are in a system header, we ignore it. We look at the diagnostic class
   // because we also want to ignore extensions and warnings in -Werror and
   // -pedantic-errors modes, which *map* warnings/extensions to errors.
-  if (Result >= DiagnosticIDs::Warning &&
-      DiagClass != CLASS_ERROR &&
-      // Custom diagnostics always are emitted in system headers.
-      DiagID < diag::DIAG_UPPER_LIMIT &&
-      !MappingInfo.hasShowInSystemHeader() &&
-      Diag.SuppressSystemWarnings &&
-      Loc.isValid() &&
+  if (Diag.SuppressSystemWarnings && !ShowInSystemHeader && Loc.isValid() &&
       Diag.getSourceManager().isInSystemHeader(
           Diag.getSourceManager().getExpansionLoc(Loc)))
-    return DiagnosticIDs::Ignored;
+    return diag::Severity::Ignored;
 
   return Result;
 }
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index 14731f6..22beed7 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -25,16 +25,13 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include <map>
 #include <set>
 #include <string>
+#include <system_error>
 
 using namespace clang;
 
-// FIXME: Enhance libsystem to support inode and other fields.
-#include <sys/stat.h>
-
 /// NON_EXISTENT_DIR - A special value distinct from null that is used to
 /// represent a dir name that doesn't exist on the disk.
 #define NON_EXISTENT_DIR reinterpret_cast<DirectoryEntry*>((intptr_t)-1)
@@ -256,7 +253,7 @@
   // FIXME: This will reduce the # syscalls.
 
   // Nope, there isn't.  Check to see if the file exists.
-  vfs::File *F = nullptr;
+  std::unique_ptr<vfs::File> F;
   FileData Data;
   if (getStatValue(InterndFileName, Data, true, openFile ? &F : nullptr)) {
     // There's no real file at the given path.
@@ -284,10 +281,6 @@
     if (DirInfo != UFE.Dir && Data.IsVFSMapped)
       UFE.Dir = DirInfo;
 
-    // If the stat process opened the file, close it to avoid a FD leak.
-    if (F)
-      delete F;
-
     return &UFE;
   }
 
@@ -300,7 +293,7 @@
   UFE.UniqueID = Data.UniqueID;
   UFE.IsNamedPipe = Data.IsNamedPipe;
   UFE.InPCH = Data.InPCH;
-  UFE.File.reset(F);
+  UFE.File = std::move(F);
   UFE.IsValid = true;
   return &UFE;
 }
@@ -388,9 +381,9 @@
 
 llvm::MemoryBuffer *FileManager::
 getBufferForFile(const FileEntry *Entry, std::string *ErrorStr,
-                 bool isVolatile) {
+                 bool isVolatile, bool ShouldCloseOpenFile) {
   std::unique_ptr<llvm::MemoryBuffer> Result;
-  llvm::error_code ec;
+  std::error_code ec;
 
   uint64_t FileSize = Entry->getSize();
   // If there's a high enough chance that the file have changed since we
@@ -405,7 +398,10 @@
                                 /*RequiresNullTerminator=*/true, isVolatile);
     if (ErrorStr)
       *ErrorStr = ec.message();
-    Entry->closeFile();
+    // FIXME: we need a set of APIs that can make guarantees about whether a
+    // FileEntry is open or not.
+    if (ShouldCloseOpenFile)
+      Entry->closeFile();
     return Result.release();
   }
 
@@ -431,7 +427,7 @@
 llvm::MemoryBuffer *FileManager::
 getBufferForFile(StringRef Filename, std::string *ErrorStr) {
   std::unique_ptr<llvm::MemoryBuffer> Result;
-  llvm::error_code ec;
+  std::error_code ec;
   if (FileSystemOpts.WorkingDir.empty()) {
     ec = FS->getBufferForFile(Filename, Result);
     if (ec && ErrorStr)
@@ -453,7 +449,7 @@
 /// false if it's an existent real file.  If FileDescriptor is NULL,
 /// do directory look-up instead of file look-up.
 bool FileManager::getStatValue(const char *Path, FileData &Data, bool isFile,
-                               vfs::File **F) {
+                               std::unique_ptr<vfs::File> *F) {
   // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
   // absolute!
   if (FileSystemOpts.WorkingDir.empty())
diff --git a/lib/Basic/FileSystemStatCache.cpp b/lib/Basic/FileSystemStatCache.cpp
index 0f16e94..7515cfb 100644
--- a/lib/Basic/FileSystemStatCache.cpp
+++ b/lib/Basic/FileSystemStatCache.cpp
@@ -52,8 +52,8 @@
 /// implementation can optionally fill in FileDescriptor with a valid
 /// descriptor and the client guarantees that it will close it.
 bool FileSystemStatCache::get(const char *Path, FileData &Data, bool isFile,
-                              vfs::File **F, FileSystemStatCache *Cache,
-                              vfs::FileSystem &FS) {
+                              std::unique_ptr<vfs::File> *F,
+                              FileSystemStatCache *Cache, vfs::FileSystem &FS) {
   LookupResult R;
   bool isForDir = !isFile;
 
@@ -79,7 +79,7 @@
     // Because of this, check to see if the file exists with 'open'.  If the
     // open succeeds, use fstat to get the stat info.
     std::unique_ptr<vfs::File> OwnedFile;
-    llvm::error_code EC = FS.openFileForRead(Path, OwnedFile);
+    std::error_code EC = FS.openFileForRead(Path, OwnedFile);
 
     if (EC) {
       // If the open fails, our "stat" fails.
@@ -92,7 +92,7 @@
       if (Status) {
         R = CacheExists;
         copyStatusToFileData(*Status, Data);
-        *F = OwnedFile.release();
+        *F = std::move(OwnedFile);
       } else {
         // fstat rarely fails.  If it does, claim the initial open didn't
         // succeed.
@@ -109,10 +109,8 @@
   // demands.
   if (Data.IsDirectory != isForDir) {
     // If not, close the file if opened.
-    if (F && *F) {
-      (*F)->close();
+    if (F)
       *F = nullptr;
-    }
     
     return true;
   }
@@ -122,7 +120,7 @@
 
 MemorizeStatCalls::LookupResult
 MemorizeStatCalls::getStat(const char *Path, FileData &Data, bool isFile,
-                           vfs::File **F, vfs::FileSystem &FS) {
+                           std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
   LookupResult Result = statChained(Path, Data, isFile, F, FS);
 
   // Do not cache failed stats, it is easy to construct common inconsistent
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index c014241..b48c02c 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -22,10 +22,10 @@
 
 OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) {
   return llvm::StringSwitch<OpenMPDirectiveKind>(Str)
-#define OPENMP_DIRECTIVE(Name) \
-           .Case(#Name, OMPD_##Name)
+#define OPENMP_DIRECTIVE(Name) .Case(#Name, OMPD_##Name)
+#define OPENMP_DIRECTIVE_EXT(Name, Str) .Case(Str, OMPD_##Name)
 #include "clang/Basic/OpenMPKinds.def"
-           .Default(OMPD_unknown);
+      .Default(OMPD_unknown);
 }
 
 const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) {
@@ -33,8 +33,12 @@
   switch (Kind) {
   case OMPD_unknown:
     return "unknown";
-#define OPENMP_DIRECTIVE(Name) \
-  case OMPD_##Name : return #Name;
+#define OPENMP_DIRECTIVE(Name)                                                 \
+  case OMPD_##Name:                                                            \
+    return #Name;
+#define OPENMP_DIRECTIVE_EXT(Name, Str)                                        \
+  case OMPD_##Name:                                                            \
+    return Str;
 #include "clang/Basic/OpenMPKinds.def"
     break;
   }
@@ -43,10 +47,9 @@
 
 OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
   return llvm::StringSwitch<OpenMPClauseKind>(Str)
-#define OPENMP_CLAUSE(Name, Class) \
-           .Case(#Name, OMPC_##Name)
+#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
 #include "clang/Basic/OpenMPKinds.def"
-           .Default(OMPC_unknown);
+      .Default(OMPC_unknown);
 }
 
 const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) {
@@ -54,8 +57,9 @@
   switch (Kind) {
   case OMPC_unknown:
     return "unknown";
-#define OPENMP_CLAUSE(Name, Class) \
-  case OMPC_##Name : return #Name;
+#define OPENMP_CLAUSE(Name, Class)                                             \
+  case OMPC_##Name:                                                            \
+    return #Name;
 #include "clang/Basic/OpenMPKinds.def"
   case OMPC_threadprivate:
     return "threadprivate or thread local";
@@ -68,16 +72,19 @@
   switch (Kind) {
   case OMPC_default:
     return llvm::StringSwitch<OpenMPDefaultClauseKind>(Str)
-#define OPENMP_DEFAULT_KIND(Name) \
-             .Case(#Name, OMPC_DEFAULT_##Name)
+#define OPENMP_DEFAULT_KIND(Name) .Case(#Name, OMPC_DEFAULT_##Name)
 #include "clang/Basic/OpenMPKinds.def"
-             .Default(OMPC_DEFAULT_unknown);
+        .Default(OMPC_DEFAULT_unknown);
   case OMPC_proc_bind:
     return llvm::StringSwitch<OpenMPProcBindClauseKind>(Str)
-#define OPENMP_PROC_BIND_KIND(Name) \
-             .Case(#Name, OMPC_PROC_BIND_##Name)
+#define OPENMP_PROC_BIND_KIND(Name) .Case(#Name, OMPC_PROC_BIND_##Name)
 #include "clang/Basic/OpenMPKinds.def"
-             .Default(OMPC_PROC_BIND_unknown);
+        .Default(OMPC_PROC_BIND_unknown);
+  case OMPC_schedule:
+    return llvm::StringSwitch<OpenMPScheduleClauseKind>(Str)
+#define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+        .Default(OMPC_SCHEDULE_unknown);
   case OMPC_unknown:
   case OMPC_threadprivate:
   case OMPC_if:
@@ -86,9 +93,15 @@
   case OMPC_collapse:
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
+  case OMPC_reduction:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
     break;
   }
   llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -101,8 +114,9 @@
     switch (Type) {
     case OMPC_DEFAULT_unknown:
       return "unknown";
-#define OPENMP_DEFAULT_KIND(Name) \
-    case OMPC_DEFAULT_##Name : return #Name;
+#define OPENMP_DEFAULT_KIND(Name)                                              \
+  case OMPC_DEFAULT_##Name:                                                    \
+    return #Name;
 #include "clang/Basic/OpenMPKinds.def"
     }
     llvm_unreachable("Invalid OpenMP 'default' clause type");
@@ -110,11 +124,22 @@
     switch (Type) {
     case OMPC_PROC_BIND_unknown:
       return "unknown";
-#define OPENMP_PROC_BIND_KIND(Name) \
-    case OMPC_PROC_BIND_##Name : return #Name;
+#define OPENMP_PROC_BIND_KIND(Name)                                            \
+  case OMPC_PROC_BIND_##Name:                                                  \
+    return #Name;
 #include "clang/Basic/OpenMPKinds.def"
     }
     llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
+  case OMPC_schedule:
+    switch (Type) {
+    case OMPC_SCHEDULE_unknown:
+      return "unknown";
+#define OPENMP_SCHEDULE_KIND(Name)                                             \
+  case OMPC_SCHEDULE_##Name:                                                   \
+    return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+    }
+    llvm_unreachable("Invalid OpenMP 'schedule' clause type");
   case OMPC_unknown:
   case OMPC_threadprivate:
   case OMPC_if:
@@ -123,9 +148,15 @@
   case OMPC_collapse:
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
+  case OMPC_reduction:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
     break;
   }
   llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -138,8 +169,9 @@
   switch (DKind) {
   case OMPD_parallel:
     switch (CKind) {
-#define OPENMP_PARALLEL_CLAUSE(Name) \
-    case OMPC_##Name: return true;
+#define OPENMP_PARALLEL_CLAUSE(Name)                                           \
+  case OMPC_##Name:                                                            \
+    return true;
 #include "clang/Basic/OpenMPKinds.def"
     default:
       break;
@@ -147,8 +179,59 @@
     break;
   case OMPD_simd:
     switch (CKind) {
-#define OPENMP_SIMD_CLAUSE(Name) \
-    case OMPC_##Name: return true;
+#define OPENMP_SIMD_CLAUSE(Name)                                               \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_for:
+    switch (CKind) {
+#define OPENMP_FOR_CLAUSE(Name)                                                \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_sections:
+    switch (CKind) {
+#define OPENMP_SECTIONS_CLAUSE(Name)                                           \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_single:
+    switch (CKind) {
+#define OPENMP_SINGLE_CLAUSE(Name)                                             \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_parallel_for:
+    switch (CKind) {
+#define OPENMP_PARALLEL_FOR_CLAUSE(Name)                                       \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_parallel_sections:
+    switch (CKind) {
+#define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)                                  \
+  case OMPC_##Name:                                                            \
+    return true;
 #include "clang/Basic/OpenMPKinds.def"
     default:
       break;
@@ -157,7 +240,40 @@
   case OMPD_unknown:
   case OMPD_threadprivate:
   case OMPD_task:
+  case OMPD_section:
     break;
   }
   return false;
 }
+
+bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_simd || DKind == OMPD_for ||
+         DKind == OMPD_parallel_for; // TODO add next directives.
+}
+
+bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_for || DKind == OMPD_sections || DKind == OMPD_section ||
+         DKind == OMPD_single || DKind == OMPD_parallel_for ||
+         DKind == OMPD_parallel_sections; // TODO add next directives.
+}
+
+bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_parallel || DKind == OMPD_parallel_for ||
+         DKind == OMPD_parallel_sections; // TODO add next directives.
+}
+
+bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_simd; // TODO || DKind == OMPD_for_simd || ...
+}
+
+bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
+  return Kind == OMPC_private || Kind == OMPC_firstprivate ||
+         Kind == OMPC_lastprivate || Kind == OMPC_linear ||
+         Kind == OMPC_reduction; // TODO add next clauses like 'reduction'.
+}
+
+bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
+  return Kind == OMPC_threadprivate ||
+         Kind == OMPC_copyin; // TODO add next clauses like 'copyprivate'.
+}
+
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index d2d5562..61dfe35 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -26,7 +26,6 @@
 #include <algorithm>
 #include <cstring>
 #include <string>
-#include <sys/stat.h>
 
 using namespace clang;
 using namespace SrcMgr;
@@ -55,8 +54,8 @@
   // Should be unreachable, but keep for sanity.
   if (!Buffer.getPointer())
     return llvm::MemoryBuffer::MemoryBuffer_Malloc;
-  
-  const llvm::MemoryBuffer *buf = Buffer.getPointer();
+
+  llvm::MemoryBuffer *buf = Buffer.getPointer();
   return buf->getBufferKind();
 }
 
@@ -69,8 +68,7 @@
                              : (unsigned) ContentsEntry->getSize();
 }
 
-void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B,
-                                 bool DoNotFree) {
+void ContentCache::replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree) {
   if (B && B == Buffer.getPointer()) {
     assert(0 && "Replacing with the same buffer");
     Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
@@ -83,10 +81,10 @@
   Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
 }
 
-const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
-                                                  const SourceManager &SM,
-                                                  SourceLocation Loc,
-                                                  bool *Invalid) const {
+llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
+                                            const SourceManager &SM,
+                                            SourceLocation Loc,
+                                            bool *Invalid) const {
   // Lazily create the Buffer for ContentCaches that wrap files.  If we already
   // computed it, just return what we have.
   if (Buffer.getPointer() || !ContentsEntry) {
@@ -462,8 +460,8 @@
 
 /// createMemBufferContentCache - Create a new ContentCache for the specified
 ///  memory buffer.  This does no caching.
-const ContentCache*
-SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
+const ContentCache *
+SourceManager::createMemBufferContentCache(llvm::MemoryBuffer *Buffer) {
   // Add a new ContentCache to the MemBufferInfos list and return it.
   ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>();
   new (Entry) ContentCache();
@@ -505,7 +503,7 @@
 
 /// \brief As part of recovering from missing or changed content, produce a
 /// fake, non-empty buffer.
-const llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
+llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
   if (!FakeBufferForRecovery)
     FakeBufferForRecovery
       = llvm::MemoryBuffer::getMemBuffer("<<<INVALID BUFFER>>");
@@ -644,16 +642,15 @@
   return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
 }
 
-const llvm::MemoryBuffer *
-SourceManager::getMemoryBufferForFile(const FileEntry *File,
-                                      bool *Invalid) {
+llvm::MemoryBuffer *SourceManager::getMemoryBufferForFile(const FileEntry *File,
+                                                          bool *Invalid) {
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
   assert(IR && "getOrCreateContentCache() cannot return NULL");
   return IR->getBuffer(Diag, *this, SourceLocation(), Invalid);
 }
 
 void SourceManager::overrideFileContents(const FileEntry *SourceFile,
-                                         const llvm::MemoryBuffer *Buffer,
+                                         llvm::MemoryBuffer *Buffer,
                                          bool DoNotFree) {
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
   assert(IR && "getOrCreateContentCache() cannot return NULL");
@@ -696,10 +693,9 @@
       *Invalid = true;
     return "<<<<<INVALID SOURCE LOCATION>>>>>";
   }
-  
-  const llvm::MemoryBuffer *Buf
-    = SLoc.getFile().getContentCache()->getBuffer(Diag, *this, SourceLocation(), 
-                                                  &MyInvalid);
+
+  llvm::MemoryBuffer *Buf = SLoc.getFile().getContentCache()->getBuffer(
+      Diag, *this, SourceLocation(), &MyInvalid);
   if (Invalid)
     *Invalid = MyInvalid;
 
@@ -1117,9 +1113,8 @@
     
     return "<<<<INVALID BUFFER>>>>";
   }
-  const llvm::MemoryBuffer *Buffer
-    = Entry.getFile().getContentCache()
-                  ->getBuffer(Diag, *this, SourceLocation(), &CharDataInvalid);
+  llvm::MemoryBuffer *Buffer = Entry.getFile().getContentCache()->getBuffer(
+      Diag, *this, SourceLocation(), &CharDataInvalid);
   if (Invalid)
     *Invalid = CharDataInvalid;
   return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
@@ -1131,7 +1126,7 @@
 unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
                                         bool *Invalid) const {
   bool MyInvalid = false;
-  const llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
+  llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
   if (Invalid)
     *Invalid = MyInvalid;
 
@@ -1205,8 +1200,7 @@
                                llvm::BumpPtrAllocator &Alloc,
                                const SourceManager &SM, bool &Invalid) {
   // Note that calling 'getBuffer()' may lazily page in the file.
-  const MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(),
-                                             &Invalid);
+  MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(), &Invalid);
   if (Invalid)
     return;
 
@@ -1763,7 +1757,7 @@
     return FileLoc.getLocWithOffset(Size);
   }
 
-  const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
+  llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
   unsigned FilePos = Content->SourceLineCache[Line - 1];
   const char *Buf = Buffer->getBufferStart() + FilePos;
   unsigned BufLength = Buffer->getBufferSize() - FilePos;
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index 4d06648..adaa2e8 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -168,6 +168,21 @@
   return NoInt;
 }
 
+TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
+                                                       bool IsSigned) const {
+  if (getCharWidth() >= BitWidth)
+    return IsSigned ? SignedChar : UnsignedChar;
+  if (getShortWidth() >= BitWidth)
+    return IsSigned ? SignedShort : UnsignedShort;
+  if (getIntWidth() >= BitWidth)
+    return IsSigned ? SignedInt : UnsignedInt;
+  if (getLongWidth() >= BitWidth)
+    return IsSigned ? SignedLong : UnsignedLong;
+  if (getLongLongWidth() >= BitWidth)
+    return IsSigned ? SignedLongLong : UnsignedLongLong;
+  return NoInt;
+}
+
 TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const {
   if (getFloatWidth() == BitWidth)
     return Float;
@@ -227,10 +242,10 @@
   };
 }
 
-/// setForcedLangOptions - Set forced language options.
+/// adjust - Set forced language options.
 /// Apply changes to the target information with respect to certain
 /// language options which change the target configuration.
-void TargetInfo::setForcedLangOptions(LangOptions &Opts) {
+void TargetInfo::adjust(const LangOptions &Opts) {
   if (Opts.NoBitFieldTypeAlign)
     UseBitFieldTypeAlignment = false;
   if (Opts.ShortWChar)
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 9343542..c88fed1 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -572,7 +572,7 @@
   void getVisualStudioDefines(const LangOptions &Opts,
                               MacroBuilder &Builder) const {
     if (Opts.CPlusPlus) {
-      if (Opts.RTTI)
+      if (Opts.RTTIData)
         Builder.defineMacro("_CPPRTTI");
 
       if (Opts.Exceptions)
@@ -587,8 +587,12 @@
     if (Opts.POSIXThreads)
       Builder.defineMacro("_MT");
 
-    if (Opts.MSCVersion != 0)
-      Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion));
+    if (Opts.MSCVersion != 0) {
+      Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion / 100000));
+      Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCVersion));
+      // FIXME We cannot encode the revision information into 32-bits
+      Builder.defineMacro("_MSC_BUILD", Twine(1));
+    }
 
     if (Opts.MicrosoftExt) {
       Builder.defineMacro("_MSC_EXTENSIONS");
@@ -702,8 +706,9 @@
     ArchDefinePwr6  = 1 << 9,
     ArchDefinePwr6x = 1 << 10,
     ArchDefinePwr7  = 1 << 11,
-    ArchDefineA2    = 1 << 12,
-    ArchDefineA2q   = 1 << 13
+    ArchDefinePwr8  = 1 << 12,
+    ArchDefineA2    = 1 << 13,
+    ArchDefineA2q   = 1 << 14
   } ArchDefineTypes;
 
   // Note: GCC recognizes the following additional cpus:
@@ -750,6 +755,8 @@
       .Case("pwr6x", true)
       .Case("power7", true)
       .Case("pwr7", true)
+      .Case("power8", true)
+      .Case("pwr8", true)
       .Case("powerpc", true)
       .Case("ppc", true)
       .Case("powerpc64", true)
@@ -1012,7 +1019,10 @@
                      | ArchDefinePpcsq)
     .Case("pwr7",  ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6
                      | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
-                     | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
+                     | ArchDefinePpcgr | ArchDefinePpcsq)
+    .Case("pwr8",  ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x
+                     | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
+                     | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
     .Case("power3",  ArchDefinePpcgr)
     .Case("power4",  ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
     .Case("power5",  ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
@@ -1026,7 +1036,10 @@
                        | ArchDefinePpcsq)
     .Case("power7",  ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6
                        | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
-                       | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
+                       | ArchDefinePpcgr | ArchDefinePpcsq)
+    .Case("power8",  ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x
+                       | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
+                       | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
     .Default(ArchDefineNone);
 
   if (defs & ArchDefineName)
@@ -1053,6 +1066,8 @@
     Builder.defineMacro("_ARCH_PWR6X");
   if (defs & ArchDefinePwr7)
     Builder.defineMacro("_ARCH_PWR7");
+  if (defs & ArchDefinePwr8)
+    Builder.defineMacro("_ARCH_PWR8");
   if (defs & ArchDefineA2)
     Builder.defineMacro("_ARCH_A2");
   if (defs & ArchDefineA2q) {
@@ -1101,6 +1116,7 @@
     .Case("g5", true)
     .Case("pwr6", true)
     .Case("pwr7", true)
+    .Case("pwr8", true)
     .Case("ppc64", true)
     .Case("ppc64le", true)
     .Default(false);
@@ -1454,6 +1470,8 @@
   "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
 
 class R600TargetInfo : public TargetInfo {
+  static const Builtin::Info BuiltinInfo[];
+
   /// \brief The GPU profiles supported by the R600 target.
   enum GPUKind {
     GK_NONE,
@@ -1500,11 +1518,10 @@
 
   void getTargetBuiltins(const Builtin::Info *&Records,
                          unsigned &NumRecords) const override {
-    Records = nullptr;
-    NumRecords = 0;
+    Records = BuiltinInfo;
+    NumRecords = clang::R600::LastTSBuiltin - Builtin::FirstTSBuiltin;
   }
 
-
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override {
     Builder.defineMacro("__R600__");
@@ -1580,6 +1597,12 @@
   }
 };
 
+const Builtin::Info R600TargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS)                \
+  { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsR600.def"
+};
+
 } // end anonymous namespace
 
 namespace {
@@ -1863,7 +1886,7 @@
   bool hasFeature(StringRef Feature) const override;
   bool handleTargetFeatures(std::vector<std::string> &Features,
                             DiagnosticsEngine &Diags) override;
-  const char* getABI() const override {
+  StringRef getABI() const override {
     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
       return "avx";
     else if (getTriple().getArch() == llvm::Triple::x86 &&
@@ -3080,9 +3103,6 @@
     WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
   }
 };
-} // end anonymous namespace
-
-namespace {
 
 // x86-32 Windows Visual Studio target
 class MicrosoftX86_32TargetInfo : public WindowsX86_32TargetInfo {
@@ -3252,18 +3272,24 @@
 class X86_64TargetInfo : public X86TargetInfo {
 public:
   X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
-    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+    const bool IsX32{getTriple().getEnvironment() == llvm::Triple::GNUX32};
+    LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
     LongDoubleWidth = 128;
     LongDoubleAlign = 128;
     LargeArrayMinWidth = 128;
     LargeArrayAlign = 128;
     SuitableAlign = 128;
-    IntMaxType = SignedLong;
-    UIntMaxType = UnsignedLong;
-    Int64Type = SignedLong;
+    SizeType    = IsX32 ? UnsignedInt      : UnsignedLong;
+    PtrDiffType = IsX32 ? SignedInt        : SignedLong;
+    IntPtrType  = IsX32 ? SignedInt        : SignedLong;
+    IntMaxType  = IsX32 ? SignedLongLong   : SignedLong;
+    UIntMaxType = IsX32 ? UnsignedLongLong : UnsignedLong;
+    Int64Type   = IsX32 ? SignedLongLong   : SignedLong;
     RegParmMax = 6;
 
-    DescriptionString = "e-m:e-i64:64-f80:128-n8:16:32:64-S128";
+    DescriptionString = (IsX32)
+                            ? "e-m:e-" "p:32:32-" "i64:64-f80:128-n8:16:32:64-S128"
+                            : "e-m:e-"            "i64:64-f80:128-n8:16:32:64-S128";
 
     // Use fpret only for long double.
     RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
@@ -3272,10 +3298,8 @@
     ComplexLongDoubleUsesFP2Ret = true;
 
     // x86-64 has atomics up to 16 bytes.
-    // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128
-    // on CPUs with cmpxchg16b
     MaxAtomicPromoteWidth = 128;
-    MaxAtomicInlineWidth = 64;
+    MaxAtomicInlineWidth = 128;
   }
   BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::X86_64ABIBuiltinVaList;
@@ -3457,27 +3481,14 @@
   static const Builtin::Info BuiltinInfo[];
 
   static bool shouldUseInlineAtomic(const llvm::Triple &T) {
-    if (T.isOSWindows())
-      return true;
-
-    // On linux, binaries targeting old cpus call functions in libgcc to
-    // perform atomic operations. The implementation in libgcc then calls into
-    // the kernel which on armv6 and newer uses ldrex and strex. The net result
-    // is that if we assume the kernel is at least as recent as the hardware,
-    // it is safe to use atomic instructions on armv6 and newer.
-    if (!T.isOSLinux() &&
-        T.getOS() != llvm::Triple::FreeBSD &&
-        T.getOS() != llvm::Triple::NetBSD &&
-        T.getOS() != llvm::Triple::Bitrig)
-      return false;
     StringRef ArchName = T.getArchName();
     if (T.getArch() == llvm::Triple::arm ||
         T.getArch() == llvm::Triple::armeb) {
       StringRef VersionStr;
       if (ArchName.startswith("armv"))
-        VersionStr = ArchName.substr(4);
+        VersionStr = ArchName.substr(4, 1);
       else if (ArchName.startswith("armebv"))
-        VersionStr = ArchName.substr(6);
+        VersionStr = ArchName.substr(6, 1);
       else
         return false;
       unsigned Version;
@@ -3489,9 +3500,9 @@
            T.getArch() == llvm::Triple::thumbeb);
     StringRef VersionStr;
     if (ArchName.startswith("thumbv"))
-      VersionStr = ArchName.substr(6);
+      VersionStr = ArchName.substr(6, 1);
     else if (ArchName.startswith("thumbebv"))
-      VersionStr = ArchName.substr(8);
+      VersionStr = ArchName.substr(8, 1);
     else
       return false;
     unsigned Version;
@@ -3663,7 +3674,7 @@
     // zero length bitfield.
     UseZeroLengthBitfieldAlignment = true;
   }
-  const char *getABI() const override { return ABI.c_str(); }
+  StringRef getABI() const override { return ABI; }
   bool setABI(const std::string &Name) override {
     ABI = Name;
 
@@ -3819,7 +3830,8 @@
       .Cases("cortex-r4", "cortex-r5", "7R")
       .Case("swift", "7S")
       .Case("cyclone", "8A")
-      .Cases("cortex-m3", "cortex-m4", "7M")
+      .Case("cortex-m3", "7M")
+      .Case("cortex-m4", "7EM")
       .Case("cortex-m0", "6M")
       .Cases("cortex-a53", "cortex-a57", "8A")
       .Default(nullptr);
@@ -3837,10 +3849,29 @@
     if (!getCPUDefineSuffix(Name))
       return false;
 
+    // Cortex M does not support 8 byte atomics, while general Thumb2 does.
+    StringRef Profile = getCPUProfile(Name);
+    if (Profile == "M" && MaxAtomicInlineWidth) {
+      MaxAtomicPromoteWidth = 32;
+      MaxAtomicInlineWidth = 32;
+    }
+
     CPU = Name;
     return true;
   }
   bool setFPMath(StringRef Name) override;
+  bool supportsThumb(StringRef ArchName, StringRef CPUArch,
+                     unsigned CPUArchVer) const {
+    return CPUArchVer >= 7 || (CPUArch.find('T') != StringRef::npos) ||
+           (CPUArch.find('M') != StringRef::npos);
+  }
+  bool supportsThumb2(StringRef ArchName, StringRef CPUArch,
+                      unsigned CPUArchVer) const {
+    // We check both CPUArchVer and ArchName because when only triple is
+    // specified, the default CPU is arm1136j-s.
+    return ArchName.endswith("v6t2") || ArchName.endswith("v7") ||
+           ArchName.endswith("v8") || CPUArch == "6T2" || CPUArchVer >= 7;
+  }
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override {
     // Target identification.
@@ -3856,10 +3887,40 @@
       llvm_unreachable("Invalid char for architecture version number");
     }
     Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
-    Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
+
+    // ACLE 6.4.1 ARM/Thumb instruction set architecture
     StringRef CPUProfile = getCPUProfile(CPU);
+    StringRef ArchName = getTriple().getArchName();
+
+    // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
+    Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
+
+    // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
+    // is not defined for the M-profile.
+    // NOTE that the deffault profile is assumed to be 'A'
+    if (CPUProfile.empty() || CPUProfile != "M")
+      Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
+
+    // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supporst the original
+    // Thumb ISA (including v6-M).  It is set to 2 if the core supports the
+    // Thumb-2 ISA as found in the v6T2 architecture and all v7 architecture.
+    if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
+      Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
+    else if (supportsThumb(ArchName, CPUArch, CPUArchVer))
+      Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
+
+    // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
+    // instruction set such as ARM or Thumb.
+    Builder.defineMacro("__ARM_32BIT_STATE", "1");
+
+    // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
+
+    // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
     if (!CPUProfile.empty())
-      Builder.defineMacro("__ARM_ARCH_PROFILE", CPUProfile);
+      Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
+
+    // ACLE predefines.
+    Builder.defineMacro("__ARM_ACLE", "200");
 
     // Subtarget options.
 
@@ -3889,11 +3950,7 @@
     if (IsThumb) {
       Builder.defineMacro("__THUMBEL__");
       Builder.defineMacro("__thumb__");
-      // We check both CPUArchVer and ArchName because when only triple is
-      // specified, the default CPU is arm1136j-s.
-      StringRef ArchName = getTriple().getArchName();
-      if (CPUArch == "6T2" || CPUArchVer >= 7 || ArchName.endswith("v6t2") ||
-          ArchName.endswith("v7") || ArchName.endswith("v8"))
+      if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
         Builder.defineMacro("__thumb2__");
     }
     if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb))
@@ -4115,6 +4172,7 @@
 #include "clang/Basic/BuiltinsNEON.def"
 
 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) { #ID, TYPE, ATTRS, 0, LANG },
 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
                                               ALL_LANGUAGES },
 #include "clang/Basic/BuiltinsARM.def"
@@ -4174,6 +4232,9 @@
     // 31: VFPv3 40: VFPv4
     Builder.defineMacro("_M_ARM_FP", "31");
   }
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::CharPtrBuiltinVaList;
+  }
 };
 
 // Windows ARM + Itanium C++ ABI Target
@@ -4245,6 +4306,7 @@
     NeonMode
   };
 
+  std::string CPU;
   unsigned FPU;
   unsigned CRC;
   unsigned Crypto;
@@ -4289,7 +4351,7 @@
     TheCXXABI.set(TargetCXXABI::GenericAArch64);
   }
 
-  virtual const char *getABI() const { return ABI.c_str(); }
+  StringRef getABI() const override { return ABI; }
   virtual bool setABI(const std::string &Name) {
     if (Name != "aapcs" && Name != "darwinpcs")
       return false;
@@ -4304,6 +4366,8 @@
                         .Cases("cortex-a53", "cortex-a57", true)
                         .Case("cyclone", true)
                         .Default(false);
+    if (CPUKnown)
+      CPU = Name;
     return CPUKnown;
   }
 
@@ -4375,6 +4439,23 @@
       (Feature == "neon" && FPU == NeonMode);
   }
 
+  void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
+
+  if (CPU == "cyclone") {
+    Features["fp-armv8"] = true;
+    Features["neon"] = true;
+    Features["crypto"] = true;
+    Features["crc"] = true;
+    Features["zcm"] = true;
+    Features["zcz"] = true;
+  } else if (CPU == "cortex-a53" || CPU == "cortex-a57") {
+    Features["fp-armv8"] = true;
+    Features["neon"] = true;
+    Features["crypto"] = true;
+    Features["crc"] = true;
+  }
+}
+
   bool handleTargetFeatures(std::vector<std::string> &Features,
                             DiagnosticsEngine &Diags) override {
     FPU = FPUMode;
@@ -5224,12 +5305,35 @@
         IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
         DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {}
 
-  const char *getABI() const override { return ABI.c_str(); }
-  bool setABI(const std::string &Name) override = 0;
-  bool setCPU(const std::string &Name) override {
-    CPU = Name;
-    return true;
+  bool isNaN2008Default() const {
+    return CPU == "mips32r6" || CPU == "mips64r6";
   }
+
+  bool isFP64Default() const {
+    return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
+  }
+
+  StringRef getABI() const override { return ABI; }
+  bool setCPU(const std::string &Name) override {
+    bool IsMips32 = getTriple().getArch() == llvm::Triple::mips ||
+                    getTriple().getArch() == llvm::Triple::mipsel;
+    CPU = Name;
+    return llvm::StringSwitch<bool>(Name)
+        .Case("mips1", IsMips32)
+        .Case("mips2", IsMips32)
+        .Case("mips3", true)
+        .Case("mips4", true)
+        .Case("mips5", true)
+        .Case("mips32", IsMips32)
+        .Case("mips32r2", IsMips32)
+        .Case("mips32r6", IsMips32)
+        .Case("mips64", true)
+        .Case("mips64r2", true)
+        .Case("mips64r6", true)
+        .Case("octeon", true)
+        .Default(false);
+  }
+  const std::string& getCPU() const { return CPU; }
   void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
     // The backend enables certain ABI's by default according to the
     // architecture.
@@ -5239,7 +5343,10 @@
     Features["n64"] = false;
 
     Features[ABI] = true;
-    Features[CPU] = true;
+    if (CPU == "octeon")
+      Features["mips64r2"] = Features["cnmips"] = true;
+    else
+      Features[CPU] = true;
   }
 
   void getTargetDefines(const LangOptions &Opts,
@@ -5376,11 +5483,11 @@
                             DiagnosticsEngine &Diags) override {
     IsMips16 = false;
     IsMicromips = false;
-    IsNan2008 = false;
+    IsNan2008 = isNaN2008Default();
     IsSingleFloat = false;
     FloatABI = HardFloat;
     DspRev = NoDSP;
-    HasFP64 = ABI == "n32" || ABI == "n64" || ABI == "64";
+    HasFP64 = isFP64Default();
 
     for (std::vector<std::string>::iterator it = Features.begin(),
          ie = Features.end(); it != ie; ++it) {
@@ -5404,6 +5511,8 @@
         HasFP64 = false;
       else if (*it == "+nan2008")
         IsNan2008 = true;
+      else if (*it == "-nan2008")
+        IsNan2008 = false;
     }
 
     // Remove front-end specific options.
@@ -5422,6 +5531,8 @@
     if (RegNo == 1) return 5;
     return -1;
   }
+
+  bool isCLZForZeroUndef() const override { return false; }
 };
 
 const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
@@ -5440,20 +5551,24 @@
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
   }
   bool setABI(const std::string &Name) override {
-    if ((Name == "o32") || (Name == "eabi")) {
+    if (Name == "o32" || Name == "eabi") {
       ABI = Name;
       return true;
-    } else if (Name == "32") {
-      ABI = "o32";
-      return true;
-    } else
-      return false;
+    }
+    return false;
   }
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override {
     MipsTargetInfoBase::getTargetDefines(Opts, Builder);
 
     Builder.defineMacro("__mips", "32");
+    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
+
+    const std::string& CPUStr = getCPU();
+    if (CPUStr == "mips32")
+      Builder.defineMacro("__mips_isa_rev", "1");
+    else if (CPUStr == "mips32r2")
+      Builder.defineMacro("__mips_isa_rev", "2");
 
     if (ABI == "o32") {
       Builder.defineMacro("__mips_o32");
@@ -5574,9 +5689,10 @@
       setN32ABITypes();
       ABI = Name;
       return true;
-    } else if (Name == "n64" || Name == "64") {
+    }
+    if (Name == "n64") {
       setN64ABITypes();
-      ABI = "n64";
+      ABI = Name;
       return true;
     }
     return false;
@@ -5589,6 +5705,13 @@
     Builder.defineMacro("__mips", "64");
     Builder.defineMacro("__mips64");
     Builder.defineMacro("__mips64__");
+    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
+
+    const std::string& CPUStr = getCPU();
+    if (CPUStr == "mips64")
+      Builder.defineMacro("__mips_isa_rev", "1");
+    else if (CPUStr == "mips64r2")
+      Builder.defineMacro("__mips_isa_rev", "2");
 
     if (ABI == "n32") {
       Builder.defineMacro("__mips_n32");
@@ -5917,6 +6040,13 @@
   default:
     return nullptr;
 
+  case llvm::Triple::xcore:
+    return new XCoreTargetInfo(Triple);
+
+  case llvm::Triple::hexagon:
+    return new HexagonTargetInfo(Triple);
+
+  case llvm::Triple::aarch64:
   case llvm::Triple::arm64:
     if (Triple.isOSDarwin())
       return new DarwinAArch64TargetInfo(Triple);
@@ -5930,33 +6060,8 @@
       return new AArch64leTargetInfo(Triple);
     }
 
-  case llvm::Triple::arm64_be:
-    switch (os) {
-    case llvm::Triple::Linux:
-      return new LinuxTargetInfo<AArch64beTargetInfo>(Triple);
-    case llvm::Triple::NetBSD:
-      return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple);
-    default:
-      return new AArch64beTargetInfo(Triple);
-    }
-
-  case llvm::Triple::xcore:
-    return new XCoreTargetInfo(Triple);
-
-  case llvm::Triple::hexagon:
-    return new HexagonTargetInfo(Triple);
-
-  case llvm::Triple::aarch64:
-    switch (os) {
-    case llvm::Triple::Linux:
-      return new LinuxTargetInfo<AArch64leTargetInfo>(Triple);
-    case llvm::Triple::NetBSD:
-      return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple);
-    default:
-      return new AArch64leTargetInfo(Triple);
-    }
-
   case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm64_be:
     switch (os) {
     case llvm::Triple::Linux:
       return new LinuxTargetInfo<AArch64beTargetInfo>(Triple);
@@ -6226,6 +6331,7 @@
         return new CygwinX86_32TargetInfo(Triple);
       case llvm::Triple::GNU:
         return new MinGWX86_32TargetInfo(Triple);
+      case llvm::Triple::Itanium:
       case llvm::Triple::MSVC:
         return new MicrosoftX86_32TargetInfo(Triple);
       }
@@ -6296,8 +6402,9 @@
 
 /// CreateTargetInfo - Return the target info object for the specified target
 /// triple.
-TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
-                                         TargetOptions *Opts) {
+TargetInfo *
+TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
+                             const std::shared_ptr<TargetOptions> &Opts) {
   llvm::Triple Triple(Opts->Triple);
 
   // Construct the target
@@ -6306,7 +6413,7 @@
     Diags.Report(diag::err_target_unknown_triple) << Triple.str();
     return nullptr;
   }
-  Target->setTargetOpts(Opts);
+  Target->TargetOpts = Opts;
 
   // Set the target CPU if specified.
   if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
index ae32c01..c2b7753 100644
--- a/lib/Basic/Version.cpp
+++ b/lib/Basic/Version.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/Basic/Version.h"
 #include "clang/Basic/LLVM.h"
-#include "llvm/Config/config.h"
+#include "clang/Config/config.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdlib>
 #include <cstring>
@@ -130,7 +130,7 @@
 
   // If vendor supplied, include the base LLVM version as well.
 #ifdef CLANG_VENDOR
-  OS << " (based on LLVM " << PACKAGE_VERSION << ")";
+  OS << " (based on " << BACKEND_PACKAGE_STRING << ")";
 #endif
 
   return OS.str();
diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp
index a469c9a..1f2a856 100644
--- a/lib/Basic/VirtualFileSystem.cpp
+++ b/lib/Basic/VirtualFileSystem.cpp
@@ -14,6 +14,8 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/YAMLParser.h"
@@ -65,17 +67,15 @@
 
 FileSystem::~FileSystem() {}
 
-error_code FileSystem::getBufferForFile(const llvm::Twine &Name,
-                                        std::unique_ptr<MemoryBuffer> &Result,
-                                        int64_t FileSize,
-                                        bool RequiresNullTerminator,
-                                        bool IsVolatile) {
+std::error_code FileSystem::getBufferForFile(
+    const llvm::Twine &Name, std::unique_ptr<MemoryBuffer> &Result,
+    int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) {
   std::unique_ptr<File> F;
-  if (error_code EC = openFileForRead(Name, F))
+  if (std::error_code EC = openFileForRead(Name, F))
     return EC;
 
-  error_code EC = F->getBuffer(Name, Result, FileSize, RequiresNullTerminator,
-                               IsVolatile);
+  std::error_code EC =
+      F->getBuffer(Name, Result, FileSize, RequiresNullTerminator, IsVolatile);
   return EC;
 }
 
@@ -96,11 +96,12 @@
 public:
   ~RealFile();
   ErrorOr<Status> status() override;
-  error_code getBuffer(const Twine &Name, std::unique_ptr<MemoryBuffer> &Result,
-                       int64_t FileSize = -1,
-                       bool RequiresNullTerminator = true,
-                       bool IsVolatile = false) override;
-  error_code close() override;
+  std::error_code getBuffer(const Twine &Name,
+                            std::unique_ptr<MemoryBuffer> &Result,
+                            int64_t FileSize = -1,
+                            bool RequiresNullTerminator = true,
+                            bool IsVolatile = false) override;
+  std::error_code close() override;
   void setName(StringRef Name) override;
 };
 } // end anonymous namespace
@@ -110,7 +111,7 @@
   assert(FD != -1 && "cannot stat closed file");
   if (!S.isStatusKnown()) {
     file_status RealStatus;
-    if (error_code EC = sys::fs::status(FD, RealStatus))
+    if (std::error_code EC = sys::fs::status(FD, RealStatus))
       return EC;
     Status NewS(RealStatus);
     NewS.setName(S.getName());
@@ -119,13 +120,19 @@
   return S;
 }
 
-error_code RealFile::getBuffer(const Twine &Name,
-                               std::unique_ptr<MemoryBuffer> &Result,
-                               int64_t FileSize, bool RequiresNullTerminator,
-                               bool IsVolatile) {
+std::error_code RealFile::getBuffer(const Twine &Name,
+                                    std::unique_ptr<MemoryBuffer> &Result,
+                                    int64_t FileSize,
+                                    bool RequiresNullTerminator,
+                                    bool IsVolatile) {
   assert(FD != -1 && "cannot get buffer for closed file");
-  return MemoryBuffer::getOpenFile(FD, Name.str().c_str(), Result, FileSize,
-                                   RequiresNullTerminator, IsVolatile);
+  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
+      MemoryBuffer::getOpenFile(FD, Name.str().c_str(), FileSize,
+                                RequiresNullTerminator, IsVolatile);
+  if (std::error_code EC = BufferOrErr.getError())
+    return EC;
+  Result = std::move(BufferOrErr.get());
+  return std::error_code();
 }
 
 // FIXME: This is terrible, we need this for ::close.
@@ -138,11 +145,11 @@
 #define S_ISFIFO(x) (0)
 #endif
 #endif
-error_code RealFile::close() {
+std::error_code RealFile::close() {
   if (::close(FD))
-    return error_code(errno, system_category());
+    return std::error_code(errno, std::generic_category());
   FD = -1;
-  return error_code::success();
+  return std::error_code();
 }
 
 void RealFile::setName(StringRef Name) {
@@ -154,28 +161,29 @@
 class RealFileSystem : public FileSystem {
 public:
   ErrorOr<Status> status(const Twine &Path) override;
-  error_code openFileForRead(const Twine &Path,
-                             std::unique_ptr<File> &Result) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
 };
 } // end anonymous namespace
 
 ErrorOr<Status> RealFileSystem::status(const Twine &Path) {
   sys::fs::file_status RealStatus;
-  if (error_code EC = sys::fs::status(Path, RealStatus))
+  if (std::error_code EC = sys::fs::status(Path, RealStatus))
     return EC;
   Status Result(RealStatus);
   Result.setName(Path.str());
   return Result;
 }
 
-error_code RealFileSystem::openFileForRead(const Twine &Name,
-                                           std::unique_ptr<File> &Result) {
+std::error_code RealFileSystem::openFileForRead(const Twine &Name,
+                                                std::unique_ptr<File> &Result) {
   int FD;
-  if (error_code EC = sys::fs::openFileForRead(Name, FD))
+  if (std::error_code EC = sys::fs::openFileForRead(Name, FD))
     return EC;
   Result.reset(new RealFile(FD));
   Result->setName(Name.str());
-  return error_code::success();
+  return std::error_code();
 }
 
 IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() {
@@ -183,6 +191,46 @@
   return FS;
 }
 
+namespace {
+class RealFSDirIter : public clang::vfs::detail::DirIterImpl {
+  std::string Path;
+  llvm::sys::fs::directory_iterator Iter;
+public:
+  RealFSDirIter(const Twine &_Path, std::error_code &EC)
+      : Path(_Path.str()), Iter(Path, EC) {
+    if (!EC && Iter != llvm::sys::fs::directory_iterator()) {
+      llvm::sys::fs::file_status S;
+      EC = Iter->status(S);
+      if (!EC) {
+        CurrentEntry = Status(S);
+        CurrentEntry.setName(Iter->path());
+      }
+    }
+  }
+
+  std::error_code increment() override {
+    std::error_code EC;
+    Iter.increment(EC);
+    if (EC) {
+      return EC;
+    } else if (Iter == llvm::sys::fs::directory_iterator()) {
+      CurrentEntry = Status();
+    } else {
+      llvm::sys::fs::file_status S;
+      EC = Iter->status(S);
+      CurrentEntry = Status(S);
+      CurrentEntry.setName(Iter->path());
+    }
+    return EC;
+  }
+};
+}
+
+directory_iterator RealFileSystem::dir_begin(const Twine &Dir,
+                                             std::error_code &EC) {
+  return directory_iterator(std::make_shared<RealFSDirIter>(Dir, EC));
+}
+
 //===-----------------------------------------------------------------------===/
 // OverlayFileSystem implementation
 //===-----------------------------------------------------------------------===/
@@ -198,21 +246,90 @@
   // FIXME: handle symlinks that cross file systems
   for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
     ErrorOr<Status> Status = (*I)->status(Path);
-    if (Status || Status.getError() != errc::no_such_file_or_directory)
+    if (Status || Status.getError() != llvm::errc::no_such_file_or_directory)
       return Status;
   }
-  return error_code(errc::no_such_file_or_directory, system_category());
+  return make_error_code(llvm::errc::no_such_file_or_directory);
 }
 
-error_code OverlayFileSystem::openFileForRead(const llvm::Twine &Path,
-                                              std::unique_ptr<File> &Result) {
+std::error_code
+OverlayFileSystem::openFileForRead(const llvm::Twine &Path,
+                                   std::unique_ptr<File> &Result) {
   // FIXME: handle symlinks that cross file systems
   for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
-    error_code EC = (*I)->openFileForRead(Path, Result);
-    if (!EC || EC != errc::no_such_file_or_directory)
+    std::error_code EC = (*I)->openFileForRead(Path, Result);
+    if (!EC || EC != llvm::errc::no_such_file_or_directory)
       return EC;
   }
-  return error_code(errc::no_such_file_or_directory, system_category());
+  return make_error_code(llvm::errc::no_such_file_or_directory);
+}
+
+clang::vfs::detail::DirIterImpl::~DirIterImpl() { }
+
+namespace {
+class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl {
+  OverlayFileSystem &Overlays;
+  std::string Path;
+  OverlayFileSystem::iterator CurrentFS;
+  directory_iterator CurrentDirIter;
+  llvm::StringSet<> SeenNames;
+
+  std::error_code incrementFS() {
+    assert(CurrentFS != Overlays.overlays_end() && "incrementing past end");
+    ++CurrentFS;
+    for (auto E = Overlays.overlays_end(); CurrentFS != E; ++CurrentFS) {
+      std::error_code EC;
+      CurrentDirIter = (*CurrentFS)->dir_begin(Path, EC);
+      if (EC && EC != errc::no_such_file_or_directory)
+        return EC;
+      if (CurrentDirIter != directory_iterator())
+        break; // found
+    }
+    return std::error_code();
+  }
+
+  std::error_code incrementDirIter(bool IsFirstTime) {
+    assert((IsFirstTime || CurrentDirIter != directory_iterator()) &&
+           "incrementing past end");
+    std::error_code EC;
+    if (!IsFirstTime)
+      CurrentDirIter.increment(EC);
+    if (!EC && CurrentDirIter == directory_iterator())
+      EC = incrementFS();
+    return EC;
+  }
+
+  std::error_code incrementImpl(bool IsFirstTime) {
+    while (true) {
+      std::error_code EC = incrementDirIter(IsFirstTime);
+      if (EC || CurrentDirIter == directory_iterator()) {
+        CurrentEntry = Status();
+        return EC;
+      }
+      CurrentEntry = *CurrentDirIter;
+      StringRef Name = llvm::sys::path::filename(CurrentEntry.getName());
+      if (SeenNames.insert(Name))
+        return EC; // name not seen before
+    }
+    llvm_unreachable("returned above");
+  }
+
+public:
+  OverlayFSDirIterImpl(const Twine &Path, OverlayFileSystem &FS,
+                       std::error_code &EC)
+      : Overlays(FS), Path(Path.str()), CurrentFS(Overlays.overlays_begin()) {
+    CurrentDirIter = (*CurrentFS)->dir_begin(Path, EC);
+    EC = incrementImpl(true);
+  }
+
+  std::error_code increment() override { return incrementImpl(false); }
+};
+} // end anonymous namespace
+
+directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir,
+                                                std::error_code &EC) {
+  return directory_iterator(
+      std::make_shared<OverlayFSDirIterImpl>(Dir, *this, EC));
 }
 
 //===-----------------------------------------------------------------------===/
@@ -291,6 +408,19 @@
   static bool classof(const Entry *E) { return E->getKind() == EK_File; }
 };
 
+class VFSFromYAML;
+
+class VFSFromYamlDirIterImpl : public clang::vfs::detail::DirIterImpl {
+  std::string Dir;
+  VFSFromYAML &FS;
+  DirectoryEntry::iterator Current, End;
+public:
+  VFSFromYamlDirIterImpl(const Twine &Path, VFSFromYAML &FS,
+                         DirectoryEntry::iterator Begin,
+                         DirectoryEntry::iterator End, std::error_code &EC);
+  std::error_code increment() override;
+};
+
 /// \brief A virtual file system parsed from a YAML file.
 ///
 /// Currently, this class allows creating virtual directories and mapping
@@ -376,6 +506,9 @@
   ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start,
                               sys::path::const_iterator End, Entry *From);
 
+  /// \brief Get the status of a given an \c Entry.
+  ErrorOr<Status> status(const Twine &Path, Entry *E);
+
 public:
   ~VFSFromYAML();
 
@@ -389,8 +522,30 @@
                              IntrusiveRefCntPtr<FileSystem> ExternalFS);
 
   ErrorOr<Status> status(const Twine &Path) override;
-  error_code openFileForRead(const Twine &Path,
-                             std::unique_ptr<File> &Result) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override{
+    ErrorOr<Entry *> E = lookupPath(Dir);
+    if (!E) {
+      EC = E.getError();
+      return directory_iterator();
+    }
+    ErrorOr<Status> S = status(Dir, *E);
+    if (!S) {
+      EC = S.getError();
+      return directory_iterator();
+    }
+    if (!S->isDirectory()) {
+      EC = std::error_code(static_cast<int>(errc::not_a_directory),
+                           std::system_category());
+      return directory_iterator();
+    }
+
+    DirectoryEntry *D = cast<DirectoryEntry>(*E);
+    return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>(Dir,
+        *this, D->contents_begin(), D->contents_end(), EC));
+  }
 };
 
 /// \brief A helper class to hold the common YAML parsing state.
@@ -740,21 +895,21 @@
   Path_.toVector(Path);
 
   // Handle relative paths
-  if (error_code EC = sys::fs::make_absolute(Path))
+  if (std::error_code EC = sys::fs::make_absolute(Path))
     return EC;
 
   if (Path.empty())
-    return error_code(errc::invalid_argument, system_category());
+    return make_error_code(llvm::errc::invalid_argument);
 
   sys::path::const_iterator Start = sys::path::begin(Path);
   sys::path::const_iterator End = sys::path::end(Path);
   for (std::vector<Entry *>::iterator I = Roots.begin(), E = Roots.end();
        I != E; ++I) {
     ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
-    if (Result || Result.getError() != errc::no_such_file_or_directory)
+    if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
       return Result;
   }
-  return error_code(errc::no_such_file_or_directory, system_category());
+  return make_error_code(llvm::errc::no_such_file_or_directory);
 }
 
 ErrorOr<Entry *> VFSFromYAML::lookupPath(sys::path::const_iterator Start,
@@ -767,7 +922,7 @@
   if (CaseSensitive ? !Start->equals(From->getName())
                     : !Start->equals_lower(From->getName()))
     // failure to match
-    return error_code(errc::no_such_file_or_directory, system_category());
+    return make_error_code(llvm::errc::no_such_file_or_directory);
 
   ++Start;
 
@@ -778,25 +933,22 @@
 
   DirectoryEntry *DE = dyn_cast<DirectoryEntry>(From);
   if (!DE)
-    return error_code(errc::not_a_directory, system_category());
+    return make_error_code(llvm::errc::not_a_directory);
 
   for (DirectoryEntry::iterator I = DE->contents_begin(),
                                 E = DE->contents_end();
        I != E; ++I) {
     ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
-    if (Result || Result.getError() != errc::no_such_file_or_directory)
+    if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
       return Result;
   }
-  return error_code(errc::no_such_file_or_directory, system_category());
+  return make_error_code(llvm::errc::no_such_file_or_directory);
 }
 
-ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
-  ErrorOr<Entry *> Result = lookupPath(Path);
-  if (!Result)
-    return Result.getError();
-
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path, Entry *E) {
+  assert(E != nullptr);
   std::string PathStr(Path.str());
-  if (FileEntry *F = dyn_cast<FileEntry>(*Result)) {
+  if (FileEntry *F = dyn_cast<FileEntry>(E)) {
     ErrorOr<Status> S = ExternalFS->status(F->getExternalContentsPath());
     assert(!S || S->getName() == F->getExternalContentsPath());
     if (S && !F->useExternalName(UseExternalNames))
@@ -805,31 +957,39 @@
       S->IsVFSMapped = true;
     return S;
   } else { // directory
-    DirectoryEntry *DE = cast<DirectoryEntry>(*Result);
+    DirectoryEntry *DE = cast<DirectoryEntry>(E);
     Status S = DE->getStatus();
     S.setName(PathStr);
     return S;
   }
 }
 
-error_code VFSFromYAML::openFileForRead(const Twine &Path,
-                                        std::unique_ptr<vfs::File> &Result) {
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
+  ErrorOr<Entry *> Result = lookupPath(Path);
+  if (!Result)
+    return Result.getError();
+  return status(Path, *Result);
+}
+
+std::error_code
+VFSFromYAML::openFileForRead(const Twine &Path,
+                             std::unique_ptr<vfs::File> &Result) {
   ErrorOr<Entry *> E = lookupPath(Path);
   if (!E)
     return E.getError();
 
   FileEntry *F = dyn_cast<FileEntry>(*E);
   if (!F) // FIXME: errc::not_a_file?
-    return error_code(errc::invalid_argument, system_category());
+    return make_error_code(llvm::errc::invalid_argument);
 
-  if (error_code EC = ExternalFS->openFileForRead(F->getExternalContentsPath(),
-                                                  Result))
+  if (std::error_code EC =
+          ExternalFS->openFileForRead(F->getExternalContentsPath(), Result))
     return EC;
 
   if (!F->useExternalName(UseExternalNames))
     Result->setName(Path.str());
 
-  return error_code::success();
+  return std::error_code();
 }
 
 IntrusiveRefCntPtr<FileSystem>
@@ -981,3 +1141,70 @@
 
   JSONWriter(OS).write(Mappings, IsCaseSensitive);
 }
+
+VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl(const Twine &_Path,
+                                               VFSFromYAML &FS,
+                                               DirectoryEntry::iterator Begin,
+                                               DirectoryEntry::iterator End,
+                                               std::error_code &EC)
+    : Dir(_Path.str()), FS(FS), Current(Begin), End(End) {
+  if (Current != End) {
+    SmallString<128> PathStr(Dir);
+    llvm::sys::path::append(PathStr, (*Current)->getName());
+    llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str());
+    if (S)
+      CurrentEntry = *S;
+    else
+      EC = S.getError();
+  }
+}
+
+std::error_code VFSFromYamlDirIterImpl::increment() {
+  assert(Current != End && "cannot iterate past end");
+  if (++Current != End) {
+    SmallString<128> PathStr(Dir);
+    llvm::sys::path::append(PathStr, (*Current)->getName());
+    llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str());
+    if (!S)
+      return S.getError();
+    CurrentEntry = *S;
+  } else {
+    CurrentEntry = Status();
+  }
+  return std::error_code();
+}
+
+vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_,
+                                                           const Twine &Path,
+                                                           std::error_code &EC)
+    : FS(&FS_) {
+  directory_iterator I = FS->dir_begin(Path, EC);
+  if (!EC && I != directory_iterator()) {
+    State = std::make_shared<IterState>();
+    State->push(I);
+  }
+}
+
+vfs::recursive_directory_iterator &
+recursive_directory_iterator::increment(std::error_code &EC) {
+  assert(FS && State && !State->empty() && "incrementing past end");
+  assert(State->top()->isStatusKnown() && "non-canonical end iterator");
+  vfs::directory_iterator End;
+  if (State->top()->isDirectory()) {
+    vfs::directory_iterator I = FS->dir_begin(State->top()->getName(), EC);
+    if (EC)
+      return *this;
+    if (I != End) {
+      State->push(I);
+      return *this;
+    }
+  }
+
+  while (!State->empty() && State->top().increment(EC) == End)
+    State->pop();
+
+  if (State->empty())
+    State.reset(); // end iterator
+
+  return *this;
+}
diff --git a/lib/Basic/Warnings.cpp b/lib/Basic/Warnings.cpp
index b09e69a..196a215 100644
--- a/lib/Basic/Warnings.cpp
+++ b/lib/Basic/Warnings.cpp
@@ -67,11 +67,11 @@
   // extension diagnostics onto WARNING or ERROR unless the user has futz'd
   // around with them explicitly.
   if (Opts.PedanticErrors)
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Error);
+    Diags.setExtensionHandlingBehavior(diag::Severity::Error);
   else if (Opts.Pedantic)
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Warn);
+    Diags.setExtensionHandlingBehavior(diag::Severity::Warning);
   else
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Ignore);
+    Diags.setExtensionHandlingBehavior(diag::Severity::Ignored);
 
   SmallVector<diag::kind, 10> _Diags;
   const IntrusiveRefCntPtr< DiagnosticIDs > DiagIDs =
@@ -106,8 +106,9 @@
 
       // Figure out how this option affects the warning.  If -Wfoo, map the
       // diagnostic to a warning, if -Wno-foo, map it to ignore.
-      diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE;
-      
+      diag::Severity Mapping =
+          isPositive ? diag::Severity::Warning : diag::Severity::Ignored;
+
       // -Wsystem-headers is a special case, not driven by the option table.  It
       // cannot be controlled with -Werror.
       if (Opt == "system-headers") {
@@ -124,7 +125,7 @@
             Diags.setEnableAllWarnings(true);
           } else {
             Diags.setEnableAllWarnings(false);
-            Diags.setMappingToAllDiagnostics(diag::MAP_IGNORE);
+            Diags.setSeverityForAll(diag::Severity::Ignored);
           }
         }
         continue;
@@ -193,7 +194,7 @@
           EmitUnknownDiagWarning(Diags, isPositive ? "-W" : "-Wno-", Opt,
                                  isPositive);
       } else {
-        Diags.setDiagnosticGroupMapping(Opt, Mapping);
+        Diags.setSeverityForGroup(Opt, Mapping);
       }
     }
   }
diff --git a/lib/CodeGen/Android.mk b/lib/CodeGen/Android.mk
index 85805e4..0a82640 100644
--- a/lib/CodeGen/Android.mk
+++ b/lib/CodeGen/Android.mk
@@ -2,6 +2,7 @@
 
 clang_codegen_TBLGEN_TABLES := \
   AttrList.inc \
+  AttrParsedAttrList.inc \
   Attrs.inc \
   AttrVisitor.inc \
   CommentCommandList.inc \
@@ -42,7 +43,6 @@
   CGOpenCLRuntime.cpp \
   CGOpenMPRuntime.cpp \
   CGLoopInfo.cpp \
-  CGRTTI.cpp \
   CGRecordLayoutBuilder.cpp \
   CGStmt.cpp \
   CGStmtOpenMP.cpp \
@@ -57,8 +57,8 @@
   CodeGenTypes.cpp \
   ItaniumCXXABI.cpp \
   MicrosoftCXXABI.cpp \
-  MicrosoftRTTI.cpp \
   ModuleBuilder.cpp \
+  SanitizerBlacklist.cpp \
   TargetInfo.cpp
 
 # For the host only
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index fc6c594..a1521dc 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -180,18 +180,8 @@
 
 static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
                                       PassManagerBase &PM) {
-  const PassManagerBuilderWrapper &BuilderWrapper =
-      static_cast<const PassManagerBuilderWrapper&>(Builder);
-  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
-  const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
-  PM.add(createAddressSanitizerFunctionPass(
-      LangOpts.Sanitize.InitOrder,
-      LangOpts.Sanitize.UseAfterReturn,
-      LangOpts.Sanitize.UseAfterScope,
-      CGOpts.SanitizerBlacklistFile));
-  PM.add(createAddressSanitizerModulePass(
-      LangOpts.Sanitize.InitOrder,
-      CGOpts.SanitizerBlacklistFile));
+  PM.add(createAddressSanitizerFunctionPass());
+  PM.add(createAddressSanitizerModulePass());
 }
 
 static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
@@ -199,8 +189,7 @@
   const PassManagerBuilderWrapper &BuilderWrapper =
       static_cast<const PassManagerBuilderWrapper&>(Builder);
   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
-  PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins,
-                                   CGOpts.SanitizerBlacklistFile));
+  PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins));
 
   // MemorySanitizer inserts complex instrumentation that mostly follows
   // the logic of the original code, but operates on "shadow" values.
@@ -217,10 +206,7 @@
 
 static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
                                    PassManagerBase &PM) {
-  const PassManagerBuilderWrapper &BuilderWrapper =
-      static_cast<const PassManagerBuilderWrapper&>(Builder);
-  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
-  PM.add(createThreadSanitizerPass(CGOpts.SanitizerBlacklistFile));
+  PM.add(createThreadSanitizerPass());
 }
 
 static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index 18eb065..89bde2c 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -174,7 +174,7 @@
   return true;
 }
 
-static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E,
+static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
                               llvm::Value *Dest, llvm::Value *Ptr,
                               llvm::Value *Val1, llvm::Value *Val2,
                               uint64_t Size, unsigned Align,
@@ -186,13 +186,15 @@
   llvm::LoadInst *Desired = CGF.Builder.CreateLoad(Val2);
   Desired->setAlignment(Align);
 
-  llvm::AtomicCmpXchgInst *Old = CGF.Builder.CreateAtomicCmpXchg(
+  llvm::AtomicCmpXchgInst *Pair = CGF.Builder.CreateAtomicCmpXchg(
       Ptr, Expected, Desired, SuccessOrder, FailureOrder);
-  Old->setVolatile(E->isVolatile());
+  Pair->setVolatile(E->isVolatile());
+  Pair->setWeak(IsWeak);
 
   // Cmp holds the result of the compare-exchange operation: true on success,
   // false on failure.
-  llvm::Value *Cmp = CGF.Builder.CreateICmpEQ(Old, Expected);
+  llvm::Value *Old = CGF.Builder.CreateExtractValue(Pair, 0);
+  llvm::Value *Cmp = CGF.Builder.CreateExtractValue(Pair, 1);
 
   // This basic block is used to hold the store instruction if the operation
   // failed.
@@ -225,8 +227,9 @@
 /// instructions to cope with the provided (but possibly only dynamically known)
 /// FailureOrder.
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
-                                        llvm::Value *Dest, llvm::Value *Ptr,
-                                        llvm::Value *Val1, llvm::Value *Val2,
+                                        bool IsWeak, llvm::Value *Dest,
+                                        llvm::Value *Ptr, llvm::Value *Val1,
+                                        llvm::Value *Val2,
                                         llvm::Value *FailureOrderVal,
                                         uint64_t Size, unsigned Align,
                                         llvm::AtomicOrdering SuccessOrder) {
@@ -249,8 +252,8 @@
       FailureOrder =
         llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder);
     }
-    emitAtomicCmpXchg(CGF, E, Dest, Ptr, Val1, Val2, Size, Align, SuccessOrder,
-                      FailureOrder);
+    emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, Align,
+                      SuccessOrder, FailureOrder);
     return;
   }
 
@@ -273,13 +276,13 @@
   // doesn't matter unless someone is crazy enough to use something that
   // doesn't fold to a constant for the ordering.
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
                     Size, Align, SuccessOrder, llvm::Monotonic);
   CGF.Builder.CreateBr(ContBB);
 
   if (AcquireBB) {
     CGF.Builder.SetInsertPoint(AcquireBB);
-    emitAtomicCmpXchg(CGF, E, Dest, Ptr, Val1, Val2,
+    emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
                       Size, Align, SuccessOrder, llvm::Acquire);
     CGF.Builder.CreateBr(ContBB);
     SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume),
@@ -289,7 +292,7 @@
   }
   if (SeqCstBB) {
     CGF.Builder.SetInsertPoint(SeqCstBB);
-    emitAtomicCmpXchg(CGF, E, Dest, Ptr, Val1, Val2,
+    emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
                       Size, Align, SuccessOrder, llvm::SequentiallyConsistent);
     CGF.Builder.CreateBr(ContBB);
     SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst),
@@ -301,8 +304,9 @@
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, llvm::Value *Dest,
                          llvm::Value *Ptr, llvm::Value *Val1, llvm::Value *Val2,
-                         llvm::Value *FailureOrder, uint64_t Size,
-                         unsigned Align, llvm::AtomicOrdering Order) {
+                         llvm::Value *IsWeak, llvm::Value *FailureOrder,
+                         uint64_t Size, unsigned Align,
+                         llvm::AtomicOrdering Order) {
   llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add;
   llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0;
 
@@ -311,12 +315,43 @@
     llvm_unreachable("Already handled!");
 
   case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
-  case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
-  case AtomicExpr::AO__atomic_compare_exchange:
-  case AtomicExpr::AO__atomic_compare_exchange_n:
-    emitAtomicCmpXchgFailureSet(CGF, E, Dest, Ptr, Val1, Val2, FailureOrder,
-                                Size, Align, Order);
+    emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
+                                FailureOrder, Size, Align, Order);
     return;
+  case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
+    emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2,
+                                FailureOrder, Size, Align, Order);
+    return;
+  case AtomicExpr::AO__atomic_compare_exchange:
+  case AtomicExpr::AO__atomic_compare_exchange_n: {
+    if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) {
+      emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr,
+                                  Val1, Val2, FailureOrder, Size, Align, Order);
+    } else {
+      // Create all the relevant BB's
+      llvm::BasicBlock *StrongBB =
+          CGF.createBasicBlock("cmpxchg.strong", CGF.CurFn);
+      llvm::BasicBlock *WeakBB = CGF.createBasicBlock("cmxchg.weak", CGF.CurFn);
+      llvm::BasicBlock *ContBB =
+          CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn);
+
+      llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(IsWeak, WeakBB);
+      SI->addCase(CGF.Builder.getInt1(false), StrongBB);
+
+      CGF.Builder.SetInsertPoint(StrongBB);
+      emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
+                                  FailureOrder, Size, Align, Order);
+      CGF.Builder.CreateBr(ContBB);
+
+      CGF.Builder.SetInsertPoint(WeakBB);
+      emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2,
+                                  FailureOrder, Size, Align, Order);
+      CGF.Builder.CreateBr(ContBB);
+
+      CGF.Builder.SetInsertPoint(ContBB);
+    }
+    return;
+  }
   case AtomicExpr::AO__c11_atomic_load:
   case AtomicExpr::AO__atomic_load_n:
   case AtomicExpr::AO__atomic_load: {
@@ -453,7 +488,8 @@
   bool UseLibcall = (Size != Align ||
                      getContext().toBits(sizeChars) > MaxInlineWidthInBits);
 
-  llvm::Value *OrderFail = nullptr, *Val1 = nullptr, *Val2 = nullptr;
+  llvm::Value *IsWeak = nullptr, *OrderFail = nullptr, *Val1 = nullptr,
+              *Val2 = nullptr;
   llvm::Value *Ptr = EmitScalarExpr(E->getPtr());
 
   if (E->getOp() == AtomicExpr::AO__c11_atomic_init) {
@@ -496,9 +532,8 @@
     else
       Val2 = EmitValToTemp(*this, E->getVal2());
     OrderFail = EmitScalarExpr(E->getOrderFail());
-    // Evaluate and discard the 'weak' argument.
     if (E->getNumSubExprs() == 6)
-      EmitScalarExpr(E->getWeak());
+      IsWeak = EmitScalarExpr(E->getWeak());
     break;
 
   case AtomicExpr::AO__c11_atomic_fetch_add:
@@ -720,30 +755,30 @@
     int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
     switch (ord) {
     case AtomicExpr::AO_ABI_memory_order_relaxed:
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                    Size, Align, llvm::Monotonic);
       break;
     case AtomicExpr::AO_ABI_memory_order_consume:
     case AtomicExpr::AO_ABI_memory_order_acquire:
       if (IsStore)
         break; // Avoid crashing on code with undefined behavior
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                    Size, Align, llvm::Acquire);
       break;
     case AtomicExpr::AO_ABI_memory_order_release:
       if (IsLoad)
         break; // Avoid crashing on code with undefined behavior
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                    Size, Align, llvm::Release);
       break;
     case AtomicExpr::AO_ABI_memory_order_acq_rel:
       if (IsLoad || IsStore)
         break; // Avoid crashing on code with undefined behavior
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                    Size, Align, llvm::AcquireRelease);
       break;
     case AtomicExpr::AO_ABI_memory_order_seq_cst:
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                    Size, Align, llvm::SequentiallyConsistent);
       break;
     default: // invalid order
@@ -781,12 +816,12 @@
 
   // Emit all the different atomics
   Builder.SetInsertPoint(MonotonicBB);
-  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                Size, Align, llvm::Monotonic);
   Builder.CreateBr(ContBB);
   if (!IsStore) {
     Builder.SetInsertPoint(AcquireBB);
-    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                  Size, Align, llvm::Acquire);
     Builder.CreateBr(ContBB);
     SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume),
@@ -796,7 +831,7 @@
   }
   if (!IsLoad) {
     Builder.SetInsertPoint(ReleaseBB);
-    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                  Size, Align, llvm::Release);
     Builder.CreateBr(ContBB);
     SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_release),
@@ -804,14 +839,14 @@
   }
   if (!IsLoad && !IsStore) {
     Builder.SetInsertPoint(AcqRelBB);
-    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                  Size, Align, llvm::AcquireRelease);
     Builder.CreateBr(ContBB);
     SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acq_rel),
                 AcqRelBB);
   }
   Builder.SetInsertPoint(SeqCstBB);
-  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, OrderFail,
+  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
                Size, Align, llvm::SequentiallyConsistent);
   Builder.CreateBr(ContBB);
   SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst),
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 21896da..7ffebe2 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -1127,11 +1127,9 @@
 
   llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo);
 
-  MangleBuffer name;
-  CGM.getBlockMangledName(GD, name, blockDecl);
-  llvm::Function *fn =
-    llvm::Function::Create(fnLLVMType, llvm::GlobalValue::InternalLinkage, 
-                           name.getString(), &CGM.getModule());
+  StringRef name = CGM.getBlockMangledName(GD, blockDecl);
+  llvm::Function *fn = llvm::Function::Create(
+      fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule());
   CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo);
 
   // Begin generating the function.
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index c6ac3cc..ded75c1 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -975,6 +975,7 @@
     Value *Result = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2],
                                                 llvm::SequentiallyConsistent,
                                                 llvm::SequentiallyConsistent);
+    Result = Builder.CreateExtractValue(Result, 0);
     Result = EmitFromInt(*this, Result, T, ValueType);
     return RValue::get(Result);
   }
@@ -998,11 +999,10 @@
     Args[1] = EmitToInt(*this, EmitScalarExpr(E->getArg(1)), T, IntType);
     Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType);
 
-    Value *OldVal = Args[1];
-    Value *PrevVal = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2],
-                                                 llvm::SequentiallyConsistent,
-                                                 llvm::SequentiallyConsistent);
-    Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal);
+    Value *Pair = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2],
+                                              llvm::SequentiallyConsistent,
+                                              llvm::SequentiallyConsistent);
+    Value *Result = Builder.CreateExtractValue(Pair, 1);
     // zext bool to int.
     Result = Builder.CreateZExt(Result, ConvertType(E->getType()));
     return RValue::get(Result);
@@ -1508,8 +1508,43 @@
   }
   case Builtin::BI__builtin_addressof:
     return RValue::get(EmitLValue(E->getArg(0)).getAddress());
+  case Builtin::BI__builtin_operator_new:
+    return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
+                                    E->getArg(0), false);
+  case Builtin::BI__builtin_operator_delete:
+    return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
+                                    E->getArg(0), true);
   case Builtin::BI__noop:
     return RValue::get(nullptr);
+  case Builtin::BI_InterlockedExchange:
+  case Builtin::BI_InterlockedExchangePointer:
+    return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
+  case Builtin::BI_InterlockedCompareExchangePointer: {
+    llvm::Type *RTy;
+    llvm::IntegerType *IntType =
+      IntegerType::get(getLLVMContext(),
+                       getContext().getTypeSize(E->getType()));
+    llvm::Type *IntPtrType = IntType->getPointerTo();
+
+    llvm::Value *Destination =
+      Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType);
+
+    llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
+    RTy = Exchange->getType();
+    Exchange = Builder.CreatePtrToInt(Exchange, IntType);
+
+    llvm::Value *Comparand =
+      Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);
+
+    auto Result = Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange,
+                                              SequentiallyConsistent,
+                                              SequentiallyConsistent);
+    Result->setVolatile(true);
+
+    return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,
+                                                                         0),
+                                              RTy));
+  }
   case Builtin::BI_InterlockedCompareExchange: {
     AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg(
         EmitScalarExpr(E->getArg(0)),
@@ -1518,7 +1553,7 @@
         SequentiallyConsistent,
         SequentiallyConsistent);
       CXI->setVolatile(true);
-      return RValue::get(CXI);
+      return RValue::get(Builder.CreateExtractValue(CXI, 0));
   }
   case Builtin::BI_InterlockedIncrement: {
     AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
@@ -1565,8 +1600,14 @@
   const char *Name = getContext().BuiltinInfo.GetName(BuiltinID);
   Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
   if (const char *Prefix =
-      llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()))
+          llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch())) {
     IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name);
+    // NOTE we dont need to perform a compatibility flag check here since the
+    // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the
+    // MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
+    if (IntrinsicID == Intrinsic::not_intrinsic)
+      IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix, Name);
+  }
 
   if (IntrinsicID != Intrinsic::not_intrinsic) {
     SmallVector<Value*, 16> Args;
@@ -1654,6 +1695,8 @@
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
     return EmitPPCBuiltinExpr(BuiltinID, E);
+  case llvm::Triple::r600:
+    return EmitR600BuiltinExpr(BuiltinID, E);
   default:
     return nullptr;
   }
@@ -1751,36 +1794,6 @@
     return Builder.CreateAShr(Vec, Shift, name);
 }
 
-Value *CodeGenFunction::EmitConcatVectors(Value *Lo, Value *Hi,
-                                          llvm::Type *ArgTy) {
-  unsigned NumElts = ArgTy->getVectorNumElements();
-  SmallVector<Constant *, 16> Indices;
-  for (unsigned i = 0; i < 2 * NumElts; ++i)
-    Indices.push_back(ConstantInt::get(Int32Ty, i));
-
-  Constant *Mask = ConstantVector::get(Indices);
-  Value *LoCast = Builder.CreateBitCast(Lo, ArgTy);
-  Value *HiCast = Builder.CreateBitCast(Hi, ArgTy);
-  return Builder.CreateShuffleVector(LoCast, HiCast, Mask, "concat");
-}
-
-Value *CodeGenFunction::EmitExtractHigh(Value *Vec, llvm::Type *ResTy) {
-  unsigned NumElts = ResTy->getVectorNumElements();
-  SmallVector<Constant *, 8> Indices;
-
-  llvm::Type *InTy = llvm::VectorType::get(ResTy->getVectorElementType(),
-                                           NumElts * 2);
-  Value *VecCast = Builder.CreateBitCast(Vec, InTy);
-
-  // extract_high is a shuffle on the second half of the input indices: E.g. 4,
-  // 5, 6, 7 if we're extracting <4 x i16> from <8 x i16>.
-  for (unsigned i = 0; i < NumElts; ++i)
-    Indices.push_back(ConstantInt::get(Int32Ty, NumElts + i));
-
-  Constant *Mask = ConstantVector::get(Indices);
-  return Builder.CreateShuffleVector(VecCast, VecCast, Mask, "concat");
-}
-
 /// GetPointeeAlignment - Given an expression with a pointer type, find the
 /// alignment of the type referenced by the pointer.  Skip over implicit
 /// casts.
@@ -2396,7 +2409,7 @@
 
 
 static const NeonIntrinsicInfo *
-findNeonIntrinsicInMap(llvm::ArrayRef<NeonIntrinsicInfo> IntrinsicMap,
+findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap,
                        unsigned BuiltinID, bool &MapProvenSorted) {
 
 #ifndef NDEBUG
@@ -2493,7 +2506,7 @@
   Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E);
 
   int j = 0;
-  ConstantInt *C0 = ConstantInt::get(CGF.Int32Ty, 0);
+  ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0);
   for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
        ai != ae; ++ai, ++j) {
     llvm::Type *ArgTy = ai->getType();
@@ -2733,7 +2746,7 @@
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
     LoadInst *Ld = Builder.CreateLoad(Ops[0]);
     Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
-    llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
+    llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
     Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
     return EmitNeonSplat(Ops[0], CI);
   }
@@ -3026,18 +3039,23 @@
   unsigned HintID = static_cast<unsigned>(-1);
   switch (BuiltinID) {
   default: break;
+  case ARM::BI__builtin_arm_yield:
   case ARM::BI__yield:
     HintID = 1;
     break;
+  case ARM::BI__builtin_arm_wfe:
   case ARM::BI__wfe:
     HintID = 2;
     break;
+  case ARM::BI__builtin_arm_wfi:
   case ARM::BI__wfi:
     HintID = 3;
     break;
+  case ARM::BI__builtin_arm_sev:
   case ARM::BI__sev:
     HintID = 4;
     break;
+  case ARM::BI__builtin_arm_sevl:
   case ARM::BI__sevl:
     HintID = 5;
     break;
@@ -3048,6 +3066,12 @@
     return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
   }
 
+  if (BuiltinID == ARM::BI__builtin_arm_rbit) {
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_rbit),
+                                               EmitScalarExpr(E->getArg(0)),
+                              "rbit");
+  }
+
   if (BuiltinID == ARM::BI__clear_cache) {
     assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
     const FunctionDecl *FD = E->getDirectCallee();
@@ -3061,9 +3085,23 @@
   }
 
   if (BuiltinID == ARM::BI__builtin_arm_ldrexd ||
-      (BuiltinID == ARM::BI__builtin_arm_ldrex &&
-       getContext().getTypeSize(E->getType()) == 64)) {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);
+      ((BuiltinID == ARM::BI__builtin_arm_ldrex ||
+        BuiltinID == ARM::BI__builtin_arm_ldaex) &&
+       getContext().getTypeSize(E->getType()) == 64) ||
+      BuiltinID == ARM::BI__ldrexd) {
+    Function *F;
+
+    switch (BuiltinID) {
+    default: llvm_unreachable("unexpected builtin");
+    case ARM::BI__builtin_arm_ldaex:
+      F = CGM.getIntrinsic(Intrinsic::arm_ldaexd);
+      break;
+    case ARM::BI__builtin_arm_ldrexd:
+    case ARM::BI__builtin_arm_ldrex:
+    case ARM::BI__ldrexd:
+      F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);
+      break;
+    }
 
     Value *LdPtr = EmitScalarExpr(E->getArg(0));
     Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
@@ -3080,7 +3118,8 @@
     return Builder.CreateBitCast(Val, ConvertType(E->getType()));
   }
 
-  if (BuiltinID == ARM::BI__builtin_arm_ldrex) {
+  if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
+      BuiltinID == ARM::BI__builtin_arm_ldaex) {
     Value *LoadAddr = EmitScalarExpr(E->getArg(0));
 
     QualType Ty = E->getType();
@@ -3089,7 +3128,10 @@
                                                   getContext().getTypeSize(Ty));
     LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo());
 
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrex, LoadAddr->getType());
+    Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex
+                                       ? Intrinsic::arm_ldaex
+                                       : Intrinsic::arm_ldrex,
+                                   LoadAddr->getType());
     Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex");
 
     if (RealResTy->isPointerTy())
@@ -3101,9 +3143,12 @@
   }
 
   if (BuiltinID == ARM::BI__builtin_arm_strexd ||
-      (BuiltinID == ARM::BI__builtin_arm_strex &&
+      ((BuiltinID == ARM::BI__builtin_arm_stlex ||
+        BuiltinID == ARM::BI__builtin_arm_strex) &&
        getContext().getTypeSize(E->getArg(0)->getType()) == 64)) {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd);
+    Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
+                                       ? Intrinsic::arm_stlexd
+                                       : Intrinsic::arm_strexd);
     llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL);
 
     Value *Tmp = CreateMemTemp(E->getArg(0)->getType());
@@ -3119,7 +3164,8 @@
     return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd");
   }
 
-  if (BuiltinID == ARM::BI__builtin_arm_strex) {
+  if (BuiltinID == ARM::BI__builtin_arm_strex ||
+      BuiltinID == ARM::BI__builtin_arm_stlex) {
     Value *StoreVal = EmitScalarExpr(E->getArg(0));
     Value *StoreAddr = EmitScalarExpr(E->getArg(1));
 
@@ -3135,7 +3181,10 @@
       StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty);
     }
 
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_strex, StoreAddr->getType());
+    Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
+                                       ? Intrinsic::arm_stlex
+                                       : Intrinsic::arm_strex,
+                                   StoreAddr->getType());
     return Builder.CreateCall2(F, StoreVal, StoreAddr, "strex");
   }
 
@@ -3336,7 +3385,7 @@
 
   // Many NEON builtins have identical semantics and uses in ARM and
   // AArch64. Emit these in a single function.
-  llvm::ArrayRef<NeonIntrinsicInfo> IntrinsicMap(ARMSIMDIntrinsicMap);
+  ArrayRef<NeonIntrinsicInfo> IntrinsicMap(ARMSIMDIntrinsicMap);
   const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
       IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted);
   if (Builtin)
@@ -3703,7 +3752,7 @@
   llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
   Op = Builder.CreateBitCast(Op, Int16Ty);
   Value *V = UndefValue::get(VTy);
-  llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
+  llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
   Op = Builder.CreateInsertElement(V, Op, CI);
   return Op;
 }
@@ -3712,7 +3761,7 @@
   llvm::Type *VTy = llvm::VectorType::get(Int8Ty, 8);
   Op = Builder.CreateBitCast(Op, Int8Ty);
   Value *V = UndefValue::get(VTy);
-  llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
+  llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
   Op = Builder.CreateInsertElement(V, Op, CI);
   return Op;
 }
@@ -3721,7 +3770,7 @@
 emitVectorWrappedScalar8Intrinsic(unsigned Int, SmallVectorImpl<Value*> &Ops,
                                   const char *Name) {
   // i8 is not a legal types for AArch64, so we can't just use
-  // a normal overloaed intrinsic call for these scalar types. Instead
+  // a normal overloaded intrinsic call for these scalar types. Instead
   // we'll build 64-bit vectors w/ lane zero being our input values and
   // perform the operation on that. The back end can pattern match directly
   // to the scalar instruction.
@@ -3729,7 +3778,7 @@
   Ops[1] = vectorWrapScalar8(Ops[1]);
   llvm::Type *VTy = llvm::VectorType::get(Int8Ty, 8);
   Value *V = EmitNeonCall(CGM.getIntrinsic(Int, VTy), Ops, Name);
-  Constant *CI = ConstantInt::get(Int32Ty, 0);
+  Constant *CI = ConstantInt::get(SizeTy, 0);
   return Builder.CreateExtractElement(V, CI, "lane0");
 }
 
@@ -3737,7 +3786,7 @@
 emitVectorWrappedScalar16Intrinsic(unsigned Int, SmallVectorImpl<Value*> &Ops,
                                    const char *Name) {
   // i16 is not a legal types for AArch64, so we can't just use
-  // a normal overloaed intrinsic call for these scalar types. Instead
+  // a normal overloaded intrinsic call for these scalar types. Instead
   // we'll build 64-bit vectors w/ lane zero being our input values and
   // perform the operation on that. The back end can pattern match directly
   // to the scalar instruction.
@@ -3745,12 +3794,27 @@
   Ops[1] = vectorWrapScalar16(Ops[1]);
   llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
   Value *V = EmitNeonCall(CGM.getIntrinsic(Int, VTy), Ops, Name);
-  Constant *CI = ConstantInt::get(Int32Ty, 0);
+  Constant *CI = ConstantInt::get(SizeTy, 0);
   return Builder.CreateExtractElement(V, CI, "lane0");
 }
 
 Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
                                                const CallExpr *E) {
+  if (BuiltinID == AArch64::BI__builtin_arm_rbit) {
+    assert((getContext().getTypeSize(E->getType()) == 32) &&
+           "rbit of unusual size!");
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    return Builder.CreateCall(
+        CGM.getIntrinsic(Intrinsic::aarch64_rbit, Arg->getType()), Arg, "rbit");
+  }
+  if (BuiltinID == AArch64::BI__builtin_arm_rbit64) {
+    assert((getContext().getTypeSize(E->getType()) == 64) &&
+           "rbit of unusual size!");
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    return Builder.CreateCall(
+        CGM.getIntrinsic(Intrinsic::aarch64_rbit, Arg->getType()), Arg, "rbit");
+  }
+
   if (BuiltinID == AArch64::BI__clear_cache) {
     assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
     const FunctionDecl *FD = E->getDirectCallee();
@@ -3763,9 +3827,12 @@
     return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
   }
 
-  if (BuiltinID == AArch64::BI__builtin_arm_ldrex &&
+  if ((BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+      BuiltinID == AArch64::BI__builtin_arm_ldaex) &&
       getContext().getTypeSize(E->getType()) == 128) {
-    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_ldxp);
+    Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
+                                       ? Intrinsic::aarch64_ldaxp
+                                       : Intrinsic::aarch64_ldxp);
 
     Value *LdPtr = EmitScalarExpr(E->getArg(0));
     Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
@@ -3781,7 +3848,8 @@
     Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
     Val = Builder.CreateOr(Val, Val1);
     return Builder.CreateBitCast(Val, ConvertType(E->getType()));
-  } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex) {
+  } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+             BuiltinID == AArch64::BI__builtin_arm_ldaex) {
     Value *LoadAddr = EmitScalarExpr(E->getArg(0));
 
     QualType Ty = E->getType();
@@ -3790,7 +3858,10 @@
                                                   getContext().getTypeSize(Ty));
     LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo());
 
-    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_ldxr, LoadAddr->getType());
+    Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
+                                       ? Intrinsic::aarch64_ldaxr
+                                       : Intrinsic::aarch64_ldxr,
+                                   LoadAddr->getType());
     Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
 
     if (RealResTy->isPointerTy())
@@ -3800,9 +3871,12 @@
     return Builder.CreateBitCast(Val, RealResTy);
   }
 
-  if (BuiltinID == AArch64::BI__builtin_arm_strex &&
+  if ((BuiltinID == AArch64::BI__builtin_arm_strex ||
+       BuiltinID == AArch64::BI__builtin_arm_stlex) &&
       getContext().getTypeSize(E->getArg(0)->getType()) == 128) {
-    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_stxp);
+    Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
+                                       ? Intrinsic::aarch64_stlxp
+                                       : Intrinsic::aarch64_stxp);
     llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty, NULL);
 
     Value *One = llvm::ConstantInt::get(Int32Ty, 1);
@@ -3819,7 +3893,8 @@
     Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)),
                                          Int8PtrTy);
     return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "stxp");
-  } else if (BuiltinID == AArch64::BI__builtin_arm_strex) {
+  } else if (BuiltinID == AArch64::BI__builtin_arm_strex ||
+             BuiltinID == AArch64::BI__builtin_arm_stlex) {
     Value *StoreVal = EmitScalarExpr(E->getArg(0));
     Value *StoreAddr = EmitScalarExpr(E->getArg(1));
 
@@ -3835,7 +3910,10 @@
       StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty);
     }
 
-    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_stxr, StoreAddr->getType());
+    Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
+                                       ? Intrinsic::aarch64_stlxr
+                                       : Intrinsic::aarch64_stxr,
+                                   StoreAddr->getType());
     return Builder.CreateCall2(F, StoreVal, StoreAddr, "stxr");
   }
 
@@ -3880,7 +3958,7 @@
   for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++)
     Ops.push_back(EmitScalarExpr(E->getArg(i)));
 
-  llvm::ArrayRef<NeonIntrinsicInfo> SISDMap(AArch64SISDIntrinsicMap);
+  ArrayRef<NeonIntrinsicInfo> SISDMap(AArch64SISDIntrinsicMap);
   const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
       SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted);
 
@@ -3950,8 +4028,8 @@
     Value *Vec = EmitScalarExpr(E->getArg(0));
     // The vector is v2f64, so make sure it's bitcast to that.
     Vec = Builder.CreateBitCast(Vec, Ty, "v2i64");
-    llvm::Value *Idx0 = llvm::ConstantInt::get(Int32Ty, 0);
-    llvm::Value *Idx1 = llvm::ConstantInt::get(Int32Ty, 1);
+    llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
+    llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
     Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
     Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
     // Pairwise addition of a v2f64 into a scalar f64.
@@ -3963,8 +4041,8 @@
     Value *Vec = EmitScalarExpr(E->getArg(0));
     // The vector is v2f64, so make sure it's bitcast to that.
     Vec = Builder.CreateBitCast(Vec, Ty, "v2f64");
-    llvm::Value *Idx0 = llvm::ConstantInt::get(Int32Ty, 0);
-    llvm::Value *Idx1 = llvm::ConstantInt::get(Int32Ty, 1);
+    llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
+    llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
     Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
     Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
     // Pairwise addition of a v2f64 into a scalar f64.
@@ -3976,8 +4054,8 @@
     Value *Vec = EmitScalarExpr(E->getArg(0));
     // The vector is v2f32, so make sure it's bitcast to that.
     Vec = Builder.CreateBitCast(Vec, Ty, "v2f32");
-    llvm::Value *Idx0 = llvm::ConstantInt::get(Int32Ty, 0);
-    llvm::Value *Idx1 = llvm::ConstantInt::get(Int32Ty, 1);
+    llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
+    llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
     Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
     Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
     // Pairwise addition of a v2f32 into a scalar f32.
@@ -4228,7 +4306,7 @@
     llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
     Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
                           ProductOps, "vqdmlXl");
-    Constant *CI = ConstantInt::get(Int32Ty, 0);
+    Constant *CI = ConstantInt::get(SizeTy, 0);
     Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
 
     unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
@@ -4325,7 +4403,7 @@
     llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
     Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
                           ProductOps, "vqdmlXl");
-    Constant *CI = ConstantInt::get(Int32Ty, 0);
+    Constant *CI = ConstantInt::get(SizeTy, 0);
     Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
     Ops.pop_back();
 
@@ -5611,7 +5689,7 @@
 
     // extract (0, 1)
     unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
-    llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index);
+    llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index);
     Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
 
     // cast pointer to i64 & store
@@ -5896,3 +5974,38 @@
   }
   }
 }
+
+Value *CodeGenFunction::EmitR600BuiltinExpr(unsigned BuiltinID,
+                                            const CallExpr *E) {
+  switch (BuiltinID) {
+  case R600::BI__builtin_amdgpu_div_scale:
+  case R600::BI__builtin_amdgpu_div_scalef: {
+    // Translate from the intrinsics's struct return to the builtin's out
+    // argument.
+
+    std::pair<llvm::Value *, unsigned> FlagOutPtr
+      = EmitPointerWithAlignment(E->getArg(3));
+
+    llvm::Value *X = EmitScalarExpr(E->getArg(0));
+    llvm::Value *Y = EmitScalarExpr(E->getArg(1));
+    llvm::Value *Z = EmitScalarExpr(E->getArg(2));
+
+    llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::AMDGPU_div_scale,
+                                           X->getType());
+
+    llvm::Value *Tmp = Builder.CreateCall3(Callee, X, Y, Z);
+
+    llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0);
+    llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1);
+
+    llvm::Type *RealFlagType
+      = FlagOutPtr.first->getType()->getPointerElementType();
+
+    llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType);
+    llvm::StoreInst *FlagStore = Builder.CreateStore(FlagExt, FlagOutPtr.first);
+    FlagStore->setAlignment(FlagOutPtr.second);
+    return Result;
+  } default:
+    return nullptr;
+  }
+}
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 55c06f6..545c5ef 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -44,6 +44,10 @@
   if (!D->hasTrivialBody())
     return true;
 
+  // For exported destructors, we need a full definition.
+  if (D->hasAttr<DLLExportAttr>())
+    return true;
+
   const CXXRecordDecl *Class = D->getParent();
 
   // If we need to manipulate a VTT parameter, give up.
@@ -138,9 +142,9 @@
   // which case the caller is responsible for ensuring the soundness
   // of these semantics.
   auto *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
-  auto *Aliasee = dyn_cast<llvm::GlobalObject>(Ref);
-  if (!Aliasee)
-    Aliasee = cast<llvm::GlobalAlias>(Ref)->getAliasee();
+  llvm::Constant *Aliasee = Ref;
+  if (Ref->getType() != AliasType)
+    Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType);
 
   // Instead of creating as alias to a linkonce_odr, replace all of the uses
   // of the aliasee.
@@ -152,10 +156,7 @@
     // members with attribute "AlwaysInline" and expect no reference to
     // be generated. It is desirable to reenable this optimisation after
     // corresponding LLVM changes.
-    llvm::Constant *Replacement = Aliasee;
-    if (Aliasee->getType() != AliasType)
-      Replacement = llvm::ConstantExpr::getBitCast(Aliasee, AliasType);
-    Replacements[MangledName] = Replacement;
+    Replacements[MangledName] = Aliasee;
     return false;
   }
 
@@ -163,7 +164,7 @@
     /// If we don't have a definition for the destructor yet, don't
     /// emit.  We can't emit aliases to declarations; that's just not
     /// how aliases work.
-    if (Aliasee->isDeclaration())
+    if (Ref->isDeclaration())
       return true;
   }
 
@@ -176,7 +177,7 @@
 
   // Create the alias with no name.
   auto *Alias = llvm::GlobalAlias::create(AliasType->getElementType(), 0,
-                                          Linkage, "", Aliasee);
+                                          Linkage, "", Aliasee, &getModule());
 
   // Switch any previous uses to the alias.
   if (Entry) {
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index 1f0de31..55ddd66 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -311,7 +311,7 @@
 }
 
 void CGCXXABI::EmitThreadLocalInitFuncs(
-    llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+    ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
     llvm::Function *InitFunc) {
 }
 
@@ -325,31 +325,3 @@
 bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
   return false;
 }
-
-/// What sort of uniqueness rules should we use for the RTTI for the
-/// given type?
-CGCXXABI::RTTIUniquenessKind
-CGCXXABI::classifyRTTIUniqueness(QualType CanTy,
-                                 llvm::GlobalValue::LinkageTypes Linkage) {
-  if (shouldRTTIBeUnique())
-    return RUK_Unique;
-
-  // It's only necessary for linkonce_odr or weak_odr linkage.
-  if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
-      Linkage != llvm::GlobalValue::WeakODRLinkage)
-    return RUK_Unique;
-
-  // It's only necessary with default visibility.
-  if (CanTy->getVisibility() != DefaultVisibility)
-    return RUK_Unique;
-
-  // If we're not required to publish this symbol, hide it.
-  if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
-    return RUK_NonUniqueHidden;
-
-  // If we're required to publish this symbol, as we might be under an
-  // explicit instantiation, leave it with default visibility but
-  // enable string-comparisons.
-  assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
-  return RUK_NonUniqueVisible;
-}
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h
index 615ec23..b49c68a 100644
--- a/lib/CodeGen/CGCXXABI.h
+++ b/lib/CodeGen/CGCXXABI.h
@@ -207,6 +207,30 @@
                                               llvm::Value *ptr,
                                               QualType type) = 0;
 
+  virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0;
+
+  virtual bool shouldTypeidBeNullChecked(bool IsDeref,
+                                         QualType SrcRecordTy) = 0;
+  virtual void EmitBadTypeidCall(CodeGenFunction &CGF) = 0;
+  virtual llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
+                                  llvm::Value *ThisPtr,
+                                  llvm::Type *StdTypeInfoPtrTy) = 0;
+
+  virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                                  QualType SrcRecordTy) = 0;
+
+  virtual llvm::Value *
+  EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
+                      QualType SrcRecordTy, QualType DestTy,
+                      QualType DestRecordTy, llvm::BasicBlock *CastEnd) = 0;
+
+  virtual llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF,
+                                             llvm::Value *Value,
+                                             QualType SrcRecordTy,
+                                             QualType DestTy) = 0;
+
+  virtual bool EmitBadCastCall(CodeGenFunction &CGF) = 0;
+
   virtual llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
                                                  llvm::Value *This,
                                                  const CXXRecordDecl *ClassDecl,
@@ -359,7 +383,8 @@
   /// base tables.
   virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0;
 
-  virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) = 0;
+  virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
+                               GlobalDecl GD, bool ReturnAdjustment) = 0;
 
   virtual llvm::Value *performThisAdjustment(CodeGenFunction &CGF,
                                              llvm::Value *This,
@@ -484,7 +509,7 @@
   ///        initialization or non-trivial destruction for thread_local
   ///        variables, a function to perform the initialization. Otherwise, 0.
   virtual void EmitThreadLocalInitFuncs(
-      llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+      ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
       llvm::Function *InitFunc);
 
   /// Emit a reference to a non-local thread_local variable (including
@@ -493,36 +518,6 @@
   virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
                                               const VarDecl *VD,
                                               QualType LValType);
-
-  /**************************** RTTI Uniqueness ******************************/
-
-protected:
-  /// Returns true if the ABI requires RTTI type_info objects to be unique
-  /// across a program.
-  virtual bool shouldRTTIBeUnique() { return true; }
-
-public:
-  /// What sort of unique-RTTI behavior should we use?
-  enum RTTIUniquenessKind {
-    /// We are guaranteeing, or need to guarantee, that the RTTI string
-    /// is unique.
-    RUK_Unique,
-
-    /// We are not guaranteeing uniqueness for the RTTI string, so we
-    /// can demote to hidden visibility but must use string comparisons.
-    RUK_NonUniqueHidden,
-
-    /// We are not guaranteeing uniqueness for the RTTI string, so we
-    /// have to use string comparisons, but we also have to emit it with
-    /// non-hidden visibility.
-    RUK_NonUniqueVisible
-  };
-
-  /// Return the required visibility status for the given type and linkage in
-  /// the current ABI.
-  RTTIUniquenessKind
-  classifyRTTIUniqueness(QualType CanTy,
-                         llvm::GlobalValue::LinkageTypes Linkage);
 };
 
 // Create an instance of a C++ ABI class:
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index d0849d3..44fd4d8 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1200,6 +1200,9 @@
     llvm_unreachable("Invalid ABI kind for return argument");
   }
 
+  if (RetTy->isReferenceType())
+    RetAttrs.addAttribute(llvm::Attribute::NonNull);
+
   if (RetAttrs.hasAttributes())
     PAL.push_back(llvm::
                   AttributeSet::get(getLLVMContext(),
@@ -1288,6 +1291,9 @@
     }
     }
 
+    if (ParamType->isReferenceType())
+      Attrs.addAttribute(llvm::Attribute::NonNull);
+
     if (Attrs.hasAttributes())
       PAL.push_back(llvm::AttributeSet::get(getLLVMContext(), Index, Attrs));
     ++Index;
@@ -2853,28 +2859,33 @@
 
   if (ArgMemory) {
     llvm::Value *Arg = ArgMemory;
-    llvm::Type *LastParamTy =
-        IRFuncTy->getParamType(IRFuncTy->getNumParams() - 1);
-    if (Arg->getType() != LastParamTy) {
+    if (CallInfo.isVariadic()) {
+      // When passing non-POD arguments by value to variadic functions, we will
+      // end up with a variadic prototype and an inalloca call site.  In such
+      // cases, we can't do any parameter mismatch checks.  Give up and bitcast
+      // the callee.
+      unsigned CalleeAS =
+          cast<llvm::PointerType>(Callee->getType())->getAddressSpace();
+      Callee = Builder.CreateBitCast(
+          Callee, getTypes().GetFunctionType(CallInfo)->getPointerTo(CalleeAS));
+    } else {
+      llvm::Type *LastParamTy =
+          IRFuncTy->getParamType(IRFuncTy->getNumParams() - 1);
+      if (Arg->getType() != LastParamTy) {
 #ifndef NDEBUG
-      // Assert that these structs have equivalent element types.
-      llvm::StructType *FullTy = CallInfo.getArgStruct();
-      llvm::StructType *Prefix = cast<llvm::StructType>(
-          cast<llvm::PointerType>(LastParamTy)->getElementType());
-
-      // For variadic functions, the caller might supply a larger struct than
-      // the callee expects, and that's OK.
-      assert(Prefix->getNumElements() == FullTy->getNumElements() ||
-             (CallInfo.isVariadic() &&
-              Prefix->getNumElements() <= FullTy->getNumElements()));
-
-      for (llvm::StructType::element_iterator PI = Prefix->element_begin(),
-                                              PE = Prefix->element_end(),
-                                              FI = FullTy->element_begin();
-           PI != PE; ++PI, ++FI)
-        assert(*PI == *FI);
+        // Assert that these structs have equivalent element types.
+        llvm::StructType *FullTy = CallInfo.getArgStruct();
+        llvm::StructType *DeclaredTy = cast<llvm::StructType>(
+            cast<llvm::PointerType>(LastParamTy)->getElementType());
+        assert(DeclaredTy->getNumElements() == FullTy->getNumElements());
+        for (llvm::StructType::element_iterator DI = DeclaredTy->element_begin(),
+                                                DE = DeclaredTy->element_end(),
+                                                FI = FullTy->element_begin();
+             DI != DE; ++DI, ++FI)
+          assert(*DI == *FI);
 #endif
-      Arg = Builder.CreateBitCast(Arg, LastParamTy);
+        Arg = Builder.CreateBitCast(Arg, LastParamTy);
+      }
     }
     Args.push_back(Arg);
   }
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 97bea97..9427de1 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -1425,8 +1425,8 @@
 /// in reverse order of their construction.
 void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
                                         CXXDtorType DtorType) {
-  assert(!DD->isTrivial() &&
-         "Should not emit dtor epilogue for trivial dtor!");
+  assert((!DD->isTrivial() || DD->hasAttr<DLLExportAttr>()) &&
+         "Should not emit dtor epilogue for non-exported trivial dtor!");
 
   // The deleting-destructor phase just needs to call the appropriate
   // operator delete that Sema picked up.
@@ -2179,7 +2179,7 @@
     FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate();
     void *InsertPos = nullptr;
     FunctionDecl *CorrespondingCallOpSpecialization = 
-        CallOpTemplate->findSpecialization(TAL->data(), TAL->size(), InsertPos); 
+        CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
     assert(CorrespondingCallOpSpecialization);
     CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
   }
diff --git a/lib/CodeGen/CGCleanup.h b/lib/CodeGen/CGCleanup.h
index 066cdb2..1d4606f 100644
--- a/lib/CodeGen/CGCleanup.h
+++ b/lib/CodeGen/CGCleanup.h
@@ -145,7 +145,7 @@
   struct Handler {
     /// A type info value, or null (C++ null, not an LLVM null pointer)
     /// for a catch-all.
-    llvm::Value *Type;
+    llvm::Constant *Type;
 
     /// The catch handler for this type.
     llvm::BasicBlock *Block;
@@ -183,7 +183,7 @@
     setHandler(I, /*catchall*/ nullptr, Block);
   }
 
-  void setHandler(unsigned I, llvm::Value *Type, llvm::BasicBlock *Block) {
+  void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block) {
     assert(I < getNumHandlers());
     getHandlers()[I].Type = Type;
     getHandlers()[I].Block = Block;
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index e2ba70a..048c8f8 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -375,9 +375,10 @@
   TheCU = DBuilder.createCompileUnit(
       LangTag, Filename, getCurrentDirname(), Producer, LO.Optimize,
       CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers, SplitDwarfFilename,
-      DebugKind == CodeGenOptions::DebugLineTablesOnly
+      DebugKind <= CodeGenOptions::DebugLineTablesOnly
           ? llvm::DIBuilder::LineTablesOnly
-          : llvm::DIBuilder::FullDebug);
+          : llvm::DIBuilder::FullDebug,
+      DebugKind != CodeGenOptions::LocTrackingOnly);
 }
 
 /// CreateType - Get the Basic type from the cache or create a new
@@ -2341,7 +2342,7 @@
 /// getFunctionDeclaration - Return debug info descriptor to describe method
 /// declaration for the given method definition.
 llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) {
-  if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly)
+  if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly)
     return llvm::DISubprogram();
 
   const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
@@ -2386,7 +2387,7 @@
 llvm::DICompositeType CGDebugInfo::getOrCreateFunctionType(const Decl *D,
                                                            QualType FnType,
                                                            llvm::DIFile F) {
-  if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly)
+  if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly)
     // Create fake but valid subroutine type. Otherwise
     // llvm::DISubprogram::Verify() would return false, and
     // subprogram DIE will miss DW_AT_decl_file and
@@ -2579,14 +2580,11 @@
 /// CreateLexicalBlock - Creates a new lexical block node and pushes it on
 /// the stack.
 void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
-  llvm::DIDescriptor D =
-    DBuilder.createLexicalBlock(LexicalBlockStack.empty() ?
-                                llvm::DIDescriptor() :
-                                llvm::DIDescriptor(LexicalBlockStack.back()),
-                                getOrCreateFile(CurLoc),
-                                getLineNumber(CurLoc),
-                                getColumnNumber(CurLoc),
-                                0);
+  llvm::DIDescriptor D = DBuilder.createLexicalBlock(
+      llvm::DIDescriptor(LexicalBlockStack.empty() ? nullptr
+                                                   : LexicalBlockStack.back()),
+      getOrCreateFile(CurLoc), getLineNumber(CurLoc), getColumnNumber(CurLoc),
+      0);
   llvm::MDNode *DN = D;
   LexicalBlockStack.push_back(DN);
 }
@@ -3190,32 +3188,6 @@
   DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV)));
 }
 
-/// EmitGlobalVariable - Emit information about an objective-c interface.
-void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
-                                     ObjCInterfaceDecl *ID) {
-  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
-  // Create global variable debug descriptor.
-  llvm::DIFile Unit = getOrCreateFile(ID->getLocation());
-  unsigned LineNo = getLineNumber(ID->getLocation());
-
-  StringRef Name = ID->getName();
-
-  QualType T = CGM.getContext().getObjCInterfaceType(ID);
-  if (T->isIncompleteArrayType()) {
-
-    // CodeGen turns int[] into int[1] so we'll do the same here.
-    llvm::APInt ConstVal(32, 1);
-    QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
-
-    T = CGM.getContext().getConstantArrayType(ET, ConstVal,
-                                           ArrayType::Normal, 0);
-  }
-
-  DBuilder.createGlobalVariable(Name, Unit, LineNo,
-                                getOrCreateType(T, Unit),
-                                Var->hasInternalLinkage(), Var);
-}
-
 /// EmitGlobalVariable - Emit global variable's debug info.
 void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD,
                                      llvm::Constant *Init) {
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 0da6179..fc3f434 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This is the source level debug info generator for llvm translation.
+// This is the source-level debug info generator for llvm translation.
 //
 //===----------------------------------------------------------------------===//
 
@@ -273,9 +273,6 @@
   /// EmitGlobalVariable - Emit information about a global variable.
   void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
 
-  /// EmitGlobalVariable - Emit information about an objective-c interface.
-  void EmitGlobalVariable(llvm::GlobalVariable *GV, ObjCInterfaceDecl *Decl);
-
   /// EmitGlobalVariable - Emit global variable's debug info.
   void EmitGlobalVariable(const ValueDecl *VD, llvm::Constant *Init);
 
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 1869c1c..9bd61d7 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -149,32 +149,27 @@
 static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
                                      const char *Separator) {
   CodeGenModule &CGM = CGF.CGM;
-  if (CGF.getLangOpts().CPlusPlus) {
-    StringRef Name = CGM.getMangledName(&D);
-    return Name.str();
-  }
 
-  std::string ContextName;
+  if (CGF.getLangOpts().CPlusPlus)
+    return CGM.getMangledName(&D).str();
+
+  StringRef ContextName;
   if (!CGF.CurFuncDecl) {
     // Better be in a block declared in global scope.
     const NamedDecl *ND = cast<NamedDecl>(&D);
     const DeclContext *DC = ND->getDeclContext();
-    if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
-      MangleBuffer Name;
-      CGM.getBlockMangledName(GlobalDecl(), Name, BD);
-      ContextName = Name.getString();
-    }
+    if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC))
+      ContextName = CGM.getBlockMangledName(GlobalDecl(), BD);
     else
       llvm_unreachable("Unknown context for block static var decl");
-  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
-    StringRef Name = CGM.getMangledName(FD);
-    ContextName = Name.str();
-  } else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl))
+    ContextName = CGM.getMangledName(FD);
+  else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
     ContextName = CGF.CurFn->getName();
   else
     llvm_unreachable("Unknown context for static var decl");
 
-  return ContextName + Separator + D.getNameAsString();
+  return ContextName.str() + Separator + D.getNameAsString();
 }
 
 llvm::Constant *
@@ -206,6 +201,13 @@
   if (D.getTLSKind())
     CGM.setTLSMode(GV, D);
 
+  if (D.isExternallyVisible()) {
+    if (D.hasAttr<DLLImportAttr>())
+      GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
+    else if (D.hasAttr<DLLExportAttr>())
+      GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
+  }
+
   // Make sure the result is of the correct type.
   unsigned ExpectedAddrSpace = CGM.getContext().getTargetAddressSpace(Ty);
   if (AddrSpace != ExpectedAddrSpace) {
@@ -343,6 +345,8 @@
   DMEntry = castedAddr;
   CGM.setStaticLocalDeclAddress(&D, castedAddr);
 
+  CGM.reportGlobalToASan(var, D.getLocation());
+
   // Emit global variable debug descriptor for static vars.
   CGDebugInfo *DI = getDebugInfo();
   if (DI &&
@@ -800,9 +804,6 @@
 /// Should we use the LLVM lifetime intrinsics for the given local variable?
 static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,
                                      unsigned Size) {
-  // Always emit lifetime markers in -fsanitize=use-after-scope mode.
-  if (CGF.getLangOpts().Sanitize.UseAfterScope)
-    return true;
   // For now, only in optimized builds.
   if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0)
     return false;
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index c287740..6a03e9a 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -245,12 +245,14 @@
   if (!CGM.getLangOpts().Exceptions)
     Fn->setDoesNotThrow();
 
-  if (CGM.getSanOpts().Address)
-    Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
-  if (CGM.getSanOpts().Thread)
-    Fn->addFnAttr(llvm::Attribute::SanitizeThread);
-  if (CGM.getSanOpts().Memory)
-    Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
+  if (!CGM.getSanitizerBlacklist().isIn(*Fn)) {
+    if (CGM.getLangOpts().Sanitize.Address)
+      Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
+    if (CGM.getLangOpts().Sanitize.Thread)
+      Fn->addFnAttr(llvm::Attribute::SanitizeThread);
+    if (CGM.getLangOpts().Sanitize.Memory)
+      Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
+  }
 
   return Fn;
 }
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 9fa478c..1bbda5c 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -97,24 +97,6 @@
   return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
 }
 
-llvm::Constant *CodeGenFunction::getUnwindResumeFn() {
-  llvm::FunctionType *FTy =
-    llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
-
-  if (CGM.getLangOpts().SjLjExceptions)
-    return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume");
-  return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume");
-}
-
-llvm::Constant *CodeGenFunction::getUnwindResumeOrRethrowFn() {
-  llvm::FunctionType *FTy =
-    llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
-
-  if (CGM.getLangOpts().SjLjExceptions)
-    return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume_or_Rethrow");
-  return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow");
-}
-
 static llvm::Constant *getTerminateFn(CodeGenModule &CGM) {
   // void __terminate();
 
@@ -622,7 +604,7 @@
       QualType CaughtType = C->getCaughtType();
       CaughtType = CaughtType.getNonReferenceType().getUnqualifiedType();
 
-      llvm::Value *TypeInfo = nullptr;
+      llvm::Constant *TypeInfo = nullptr;
       if (CaughtType->isObjCObjectPointerType())
         TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
       else
@@ -721,56 +703,6 @@
   return LP;
 }
 
-// This code contains a hack to work around a design flaw in
-// LLVM's EH IR which breaks semantics after inlining.  This same
-// hack is implemented in llvm-gcc.
-//
-// The LLVM EH abstraction is basically a thin veneer over the
-// traditional GCC zero-cost design: for each range of instructions
-// in the function, there is (at most) one "landing pad" with an
-// associated chain of EH actions.  A language-specific personality
-// function interprets this chain of actions and (1) decides whether
-// or not to resume execution at the landing pad and (2) if so,
-// provides an integer indicating why it's stopping.  In LLVM IR,
-// the association of a landing pad with a range of instructions is
-// achieved via an invoke instruction, the chain of actions becomes
-// the arguments to the @llvm.eh.selector call, and the selector
-// call returns the integer indicator.  Other than the required
-// presence of two intrinsic function calls in the landing pad,
-// the IR exactly describes the layout of the output code.
-//
-// A principal advantage of this design is that it is completely
-// language-agnostic; in theory, the LLVM optimizers can treat
-// landing pads neutrally, and targets need only know how to lower
-// the intrinsics to have a functioning exceptions system (assuming
-// that platform exceptions follow something approximately like the
-// GCC design).  Unfortunately, landing pads cannot be combined in a
-// language-agnostic way: given selectors A and B, there is no way
-// to make a single landing pad which faithfully represents the
-// semantics of propagating an exception first through A, then
-// through B, without knowing how the personality will interpret the
-// (lowered form of the) selectors.  This means that inlining has no
-// choice but to crudely chain invokes (i.e., to ignore invokes in
-// the inlined function, but to turn all unwindable calls into
-// invokes), which is only semantically valid if every unwind stops
-// at every landing pad.
-//
-// Therefore, the invoke-inline hack is to guarantee that every
-// landing pad has a catch-all.
-enum CleanupHackLevel_t {
-  /// A level of hack that requires that all landing pads have
-  /// catch-alls.
-  CHL_MandatoryCatchall,
-
-  /// A level of hack that requires that all landing pads handle
-  /// cleanups.
-  CHL_MandatoryCleanup,
-
-  /// No hacks at all;  ideal IR generation.
-  CHL_Ideal
-};
-const CleanupHackLevel_t CleanupHackLevel = CHL_MandatoryCleanup;
-
 llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
   assert(EHStack.requiresLandingPad());
 
@@ -897,11 +829,8 @@
       LPadInst->setCleanup(true);
 
   // Otherwise, signal that we at least have cleanups.
-  } else if (CleanupHackLevel == CHL_MandatoryCatchall || hasCleanup) {
-    if (CleanupHackLevel == CHL_MandatoryCatchall)
-      LPadInst->addClause(getCatchAllValue(*this));
-    else
-      LPadInst->setCleanup(true);
+  } else if (hasCleanup) {
+    LPadInst->setCleanup(true);
   }
 
   assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
@@ -1678,52 +1607,32 @@
   const char *RethrowName = Personality.CatchallRethrowFn;
   if (RethrowName != nullptr && !isCleanup) {
     EmitRuntimeCall(getCatchallRethrowFn(CGM, RethrowName),
-                      getExceptionFromSlot())
+                    getExceptionFromSlot())
       ->setDoesNotReturn();
-  } else {
-    switch (CleanupHackLevel) {
-    case CHL_MandatoryCatchall:
-      // In mandatory-catchall mode, we need to use
-      // _Unwind_Resume_or_Rethrow, or whatever the personality's
-      // equivalent is.
-      EmitRuntimeCall(getUnwindResumeOrRethrowFn(),
-                        getExceptionFromSlot())
-        ->setDoesNotReturn();
-      break;
-    case CHL_MandatoryCleanup: {
-      // In mandatory-cleanup mode, we should use 'resume'.
-
-      // Recreate the landingpad's return value for the 'resume' instruction.
-      llvm::Value *Exn = getExceptionFromSlot();
-      llvm::Value *Sel = getSelectorFromSlot();
-
-      llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
-                                                   Sel->getType(), NULL);
-      llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
-      LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
-      LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
-
-      Builder.CreateResume(LPadVal);
-      Builder.restoreIP(SavedIP);
-      return EHResumeBlock;
-    }
-    case CHL_Ideal:
-      // In an idealized mode where we don't have to worry about the
-      // optimizer combining landing pads, we should just use
-      // _Unwind_Resume (or the personality's equivalent).
-      EmitRuntimeCall(getUnwindResumeFn(), getExceptionFromSlot())
-        ->setDoesNotReturn();
-      break;
-    }
+    Builder.CreateUnreachable();
+    Builder.restoreIP(SavedIP);
+    return EHResumeBlock;
   }
 
-  Builder.CreateUnreachable();
+  // Recreate the landingpad's return value for the 'resume' instruction.
+  llvm::Value *Exn = getExceptionFromSlot();
+  llvm::Value *Sel = getSelectorFromSlot();
 
+  llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
+                                               Sel->getType(), NULL);
+  llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
+  LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
+  LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
+
+  Builder.CreateResume(LPadVal);
   Builder.restoreIP(SavedIP);
-
   return EHResumeBlock;
 }
 
 void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {
   CGM.ErrorUnsupported(&S, "SEH __try");
 }
+
+void CodeGenFunction::EmitSEHLeaveStmt(const SEHLeaveStmt &S) {
+  CGM.ErrorUnsupported(&S, "SEH __leave");
+}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 966edc4..c99e669 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -407,7 +407,7 @@
   assert(LV.isSimple());
   llvm::Value *Value = LV.getAddress();
 
-  if (SanitizePerformTypeCheck && !E->getType()->isFunctionType()) {
+  if (sanitizePerformTypeCheck() && !E->getType()->isFunctionType()) {
     // C++11 [dcl.ref]p5 (as amended by core issue 453):
     //   If a glvalue to which a reference is directly bound designates neither
     //   an existing object or function of an appropriate type nor a region of
@@ -441,10 +441,15 @@
   return Builder.CreateMul(B1, KMul);
 }
 
+bool CodeGenFunction::sanitizePerformTypeCheck() const {
+  return SanOpts->Null | SanOpts->Alignment | SanOpts->ObjectSize |
+         SanOpts->Vptr;
+}
+
 void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
                                     llvm::Value *Address,
                                     QualType Ty, CharUnits Alignment) {
-  if (!SanitizePerformTypeCheck)
+  if (!sanitizePerformTypeCheck())
     return;
 
   // Don't check pointers outside the default address space. The null check
@@ -1331,7 +1336,7 @@
   const VectorType *ExprVT = LV.getType()->getAs<VectorType>();
   if (!ExprVT) {
     unsigned InIdx = getAccessedFieldNo(0, Elts);
-    llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
+    llvm::Value *Elt = llvm::ConstantInt::get(SizeTy, InIdx);
     return RValue::get(Builder.CreateExtractElement(Vec, Elt));
   }
 
@@ -1350,12 +1355,22 @@
 
 /// @brief Load of global gamed gegisters are always calls to intrinsics.
 RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
-  assert(LV.getType()->isIntegerType() && "Bad type for register variable");
+  assert((LV.getType()->isIntegerType() || LV.getType()->isPointerType()) &&
+         "Bad type for register variable");
   llvm::MDNode *RegName = dyn_cast<llvm::MDNode>(LV.getGlobalReg());
   assert(RegName && "Register LValue is not metadata");
-  llvm::Type *Types[] = { CGM.getTypes().ConvertType(LV.getType()) };
+
+  // We accept integer and pointer types only
+  llvm::Type *OrigTy = CGM.getTypes().ConvertType(LV.getType());
+  llvm::Type *Ty = OrigTy;
+  if (OrigTy->isPointerTy())
+    Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
+  llvm::Type *Types[] = { Ty };
+
   llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
-  llvm::Value* Call = Builder.CreateCall(F, RegName);
+  llvm::Value *Call = Builder.CreateCall(F, RegName);
+  if (OrigTy->isPointerTy())
+    Call = Builder.CreateIntToPtr(Call, OrigTy);
   return RValue::get(Call);
 }
 
@@ -1590,7 +1605,7 @@
   } else {
     // If the Src is a scalar (not a vector) it must be updating one element.
     unsigned InIdx = getAccessedFieldNo(0, Elts);
-    llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
+    llvm::Value *Elt = llvm::ConstantInt::get(SizeTy, InIdx);
     Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt);
   }
 
@@ -1601,12 +1616,22 @@
 
 /// @brief Store of global named registers are always calls to intrinsics.
 void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {
-  assert(Dst.getType()->isIntegerType() && "Bad type for register variable");
+  assert((Dst.getType()->isIntegerType() || Dst.getType()->isPointerType()) &&
+         "Bad type for register variable");
   llvm::MDNode *RegName = dyn_cast<llvm::MDNode>(Dst.getGlobalReg());
   assert(RegName && "Register LValue is not metadata");
-  llvm::Type *Types[] = { CGM.getTypes().ConvertType(Dst.getType()) };
+
+  // We accept integer and pointer types only
+  llvm::Type *OrigTy = CGM.getTypes().ConvertType(Dst.getType());
+  llvm::Type *Ty = OrigTy;
+  if (OrigTy->isPointerTy())
+    Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
+  llvm::Type *Types[] = { Ty };
+
   llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
   llvm::Value *Value = Src.getScalarVal();
+  if (OrigTy->isPointerTy())
+    Value = Builder.CreatePtrToInt(Value, Ty);
   Builder.CreateCall2(F, RegName, Value);
 }
 
@@ -1968,28 +1993,6 @@
                         E->getType());
 }
 
-static llvm::Constant*
-GetAddrOfConstantWideString(StringRef Str,
-                            const char *GlobalName,
-                            ASTContext &Context,
-                            QualType Ty, SourceLocation Loc,
-                            CodeGenModule &CGM) {
-
-  StringLiteral *SL = StringLiteral::Create(Context,
-                                            Str,
-                                            StringLiteral::Wide,
-                                            /*Pascal = */false,
-                                            Ty, Loc);
-  llvm::Constant *C = CGM.GetConstantArrayFromStringLiteral(SL);
-  auto *GV = new llvm::GlobalVariable(
-      CGM.getModule(), C->getType(), !CGM.getLangOpts().WritableStrings,
-      llvm::GlobalValue::PrivateLinkage, C, GlobalName);
-  const unsigned WideAlignment =
-    Context.getTypeAlignInChars(Ty).getQuantity();
-  GV->setAlignment(WideAlignment);
-  return GV;
-}
-
 static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
                                     SmallString<32>& Target) {
   Target.resize(CharByteWidth * (Source.size() + 1));
@@ -2058,14 +2061,12 @@
     if (ElemType->isWideCharType()) {
       SmallString<32> RawChars;
       ConvertUTF8ToWideString(
-          getContext().getTypeSizeInChars(ElemType).getQuantity(),
-          FunctionName, RawChars);
-      C = GetAddrOfConstantWideString(RawChars,
-                                      GVName.c_str(),
-                                      getContext(),
-                                      E->getType(),
-                                      E->getLocation(),
-                                      CGM);
+          getContext().getTypeSizeInChars(ElemType).getQuantity(), FunctionName,
+          RawChars);
+      StringLiteral *SL = StringLiteral::Create(
+          getContext(), RawChars, StringLiteral::Wide,
+          /*Pascal = */ false, E->getType(), E->getLocation());
+      C = CGM.GetAddrOfConstantStringFromLiteral(SL);
     } else {
       C = CGM.GetAddrOfConstantCString(FunctionName, GVName.c_str(), 1);
     }
@@ -2105,7 +2106,7 @@
   SmallString<32> Buffer;
   CGM.getDiags().ConvertArgToString(DiagnosticsEngine::ak_qualtype,
                                     (intptr_t)T.getAsOpaquePtr(),
-                                    nullptr, 0, nullptr, 0, nullptr, 0, Buffer,
+                                    StringRef(), StringRef(), None, Buffer,
                                     ArrayRef<intptr_t>());
 
   llvm::Constant *Components[] = {
@@ -2220,9 +2221,9 @@
     ArgTypes.push_back(IntPtrTy);
   }
 
-  bool Recover = (RecoverKind == CRK_AlwaysRecoverable) ||
-                 ((RecoverKind == CRK_Recoverable) &&
-                   CGM.getCodeGenOpts().SanitizeRecover);
+  bool Recover = RecoverKind == CRK_AlwaysRecoverable ||
+                 (RecoverKind == CRK_Recoverable &&
+                  CGM.getCodeGenOpts().SanitizeRecover);
 
   llvm::FunctionType *FnType =
     llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false);
@@ -2234,15 +2235,14 @@
   B.addAttribute(llvm::Attribute::UWTable);
 
   // Checks that have two variants use a suffix to differentiate them
-  bool NeedsAbortSuffix = (RecoverKind != CRK_Unrecoverable) &&
-                           !CGM.getCodeGenOpts().SanitizeRecover;
+  bool NeedsAbortSuffix = RecoverKind != CRK_Unrecoverable &&
+                          !CGM.getCodeGenOpts().SanitizeRecover;
   std::string FunctionName = ("__ubsan_handle_" + CheckName +
                               (NeedsAbortSuffix? "_abort" : "")).str();
-  llvm::Value *Fn =
-    CGM.CreateRuntimeFunction(FnType, FunctionName,
-                              llvm::AttributeSet::get(getLLVMContext(),
-                                              llvm::AttributeSet::FunctionIndex,
-                                                      B));
+  llvm::Value *Fn = CGM.CreateRuntimeFunction(
+      FnType, FunctionName,
+      llvm::AttributeSet::get(getLLVMContext(),
+                              llvm::AttributeSet::FunctionIndex, B));
   llvm::CallInst *HandlerCall = EmitNounwindRuntimeCall(Fn, Args);
   if (Recover) {
     Builder.CreateBr(Cont);
@@ -2281,7 +2281,7 @@
   // If this isn't just an array->pointer decay, bail out.
   const auto *CE = dyn_cast<CastExpr>(E);
   if (!CE || CE->getCastKind() != CK_ArrayToPointerDecay)
-    return 0;
+    return nullptr;
 
   // If this is a decay from variable width array, bail out.
   const Expr *SubExpr = CE->getSubExpr();
@@ -2307,7 +2307,6 @@
     // Emit the vector as an lvalue to get its address.
     LValue LHS = EmitLValue(E->getBase());
     assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
-    Idx = Builder.CreateIntCast(Idx, Int32Ty, IdxSigned, "vidx");
     return LValue::MakeVectorElt(LHS.getAddress(), Idx,
                                  E->getBase()->getType(), LHS.getAlignment());
   }
@@ -2690,6 +2689,19 @@
   return EmitLValue(E->getInit(0));
 }
 
+/// Emit the operand of a glvalue conditional operator. This is either a glvalue
+/// or a (possibly-parenthesized) throw-expression. If this is a throw, no
+/// LValue is returned and the current block has been terminated.
+static Optional<LValue> EmitLValueOrThrowExpression(CodeGenFunction &CGF,
+                                                    const Expr *Operand) {
+  if (auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
+    CGF.EmitCXXThrowExpr(ThrowExpr, /*KeepInsertionPoint*/false);
+    return None;
+  }
+
+  return CGF.EmitLValue(Operand);
+}
+
 LValue CodeGenFunction::
 EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
   if (!expr->isGLValue()) {
@@ -2727,31 +2739,40 @@
   EmitBlock(lhsBlock);
   Cnt.beginRegion(Builder);
   eval.begin(*this);
-  LValue lhs = EmitLValue(expr->getTrueExpr());
+  Optional<LValue> lhs =
+      EmitLValueOrThrowExpression(*this, expr->getTrueExpr());
   eval.end(*this);
 
-  if (!lhs.isSimple())
+  if (lhs && !lhs->isSimple())
     return EmitUnsupportedLValue(expr, "conditional operator");
 
   lhsBlock = Builder.GetInsertBlock();
-  Builder.CreateBr(contBlock);
+  if (lhs)
+    Builder.CreateBr(contBlock);
 
   // Any temporaries created here are conditional.
   EmitBlock(rhsBlock);
   eval.begin(*this);
-  LValue rhs = EmitLValue(expr->getFalseExpr());
+  Optional<LValue> rhs =
+      EmitLValueOrThrowExpression(*this, expr->getFalseExpr());
   eval.end(*this);
-  if (!rhs.isSimple())
+  if (rhs && !rhs->isSimple())
     return EmitUnsupportedLValue(expr, "conditional operator");
   rhsBlock = Builder.GetInsertBlock();
 
   EmitBlock(contBlock);
 
-  llvm::PHINode *phi = Builder.CreatePHI(lhs.getAddress()->getType(), 2,
-                                         "cond-lvalue");
-  phi->addIncoming(lhs.getAddress(), lhsBlock);
-  phi->addIncoming(rhs.getAddress(), rhsBlock);
-  return MakeAddrLValue(phi, expr->getType());
+  if (lhs && rhs) {
+    llvm::PHINode *phi = Builder.CreatePHI(lhs->getAddress()->getType(),
+                                           2, "cond-lvalue");
+    phi->addIncoming(lhs->getAddress(), lhsBlock);
+    phi->addIncoming(rhs->getAddress(), rhsBlock);
+    return MakeAddrLValue(phi, expr->getType());
+  } else {
+    assert((lhs || rhs) &&
+           "both operands of glvalue conditional are throw-expressions?");
+    return lhs ? *lhs : *rhs;
+  }
 }
 
 /// EmitCastLValue - Casts are never lvalues unless that cast is to a reference
@@ -2861,7 +2882,7 @@
 
     // C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is
     // performed and the object is not of the derived type.
-    if (SanitizePerformTypeCheck)
+    if (sanitizePerformTypeCheck())
       EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(),
                     Derived, E->getType());
 
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 760e6f1..b1406cd 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -370,6 +370,29 @@
   }
 }
 
+/// \brief Determine if E is a trivial array filler, that is, one that is
+/// equivalent to zero-initialization.
+static bool isTrivialFiller(Expr *E) {
+  if (!E)
+    return true;
+
+  if (isa<ImplicitValueInitExpr>(E))
+    return true;
+
+  if (auto *ILE = dyn_cast<InitListExpr>(E)) {
+    if (ILE->getNumInits())
+      return false;
+    return isTrivialFiller(ILE->getArrayFiller());
+  }
+
+  if (auto *Cons = dyn_cast_or_null<CXXConstructExpr>(E))
+    return Cons->getConstructor()->isDefaultConstructor() &&
+           Cons->getConstructor()->isTrivial();
+
+  // FIXME: Are there other cases where we can avoid emitting an initializer?
+  return false;
+}
+
 /// \brief Emit initialization of an array from an initializer list.
 void AggExprEmitter::EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,
                                    QualType elementType, InitListExpr *E) {
@@ -435,14 +458,8 @@
   }
 
   // Check whether there's a non-trivial array-fill expression.
-  // Note that this will be a CXXConstructExpr even if the element
-  // type is an array (or array of array, etc.) of class type.
   Expr *filler = E->getArrayFiller();
-  bool hasTrivialFiller = true;
-  if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) {
-    assert(cons->getConstructor()->isDefaultConstructor());
-    hasTrivialFiller = cons->getConstructor()->isTrivial();
-  }
+  bool hasTrivialFiller = isTrivialFiller(filler);
 
   // Any remaining elements need to be zero-initialized, possibly
   // using the filler expression.  We can skip this if the we're
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 548cd48..47dc9fb 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -749,207 +749,249 @@
 }
 
 void
-CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, 
-                                         QualType elementType,
-                                         llvm::Value *beginPtr,
-                                         llvm::Value *numElements) {
+CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E,
+                                         QualType ElementType,
+                                         llvm::Value *BeginPtr,
+                                         llvm::Value *NumElements,
+                                         llvm::Value *AllocSizeWithoutCookie) {
+  // If we have a type with trivial initialization and no initializer,
+  // there's nothing to do.
   if (!E->hasInitializer())
-    return; // We have a POD type.
+    return;
 
-  llvm::Value *explicitPtr = beginPtr;
-  // Find the end of the array, hoisted out of the loop.
-  llvm::Value *endPtr =
-    Builder.CreateInBoundsGEP(beginPtr, numElements, "array.end");
+  llvm::Value *CurPtr = BeginPtr;
 
-  unsigned initializerElements = 0;
+  unsigned InitListElements = 0;
 
   const Expr *Init = E->getInitializer();
-  llvm::AllocaInst *endOfInit = nullptr;
-  QualType::DestructionKind dtorKind = elementType.isDestructedType();
-  EHScopeStack::stable_iterator cleanup;
-  llvm::Instruction *cleanupDominator = nullptr;
+  llvm::AllocaInst *EndOfInit = nullptr;
+  QualType::DestructionKind DtorKind = ElementType.isDestructedType();
+  EHScopeStack::stable_iterator Cleanup;
+  llvm::Instruction *CleanupDominator = nullptr;
 
   // If the initializer is an initializer list, first do the explicit elements.
   if (const InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
-    initializerElements = ILE->getNumInits();
+    InitListElements = ILE->getNumInits();
 
     // If this is a multi-dimensional array new, we will initialize multiple
     // elements with each init list element.
     QualType AllocType = E->getAllocatedType();
     if (const ConstantArrayType *CAT = dyn_cast_or_null<ConstantArrayType>(
             AllocType->getAsArrayTypeUnsafe())) {
-      unsigned AS = explicitPtr->getType()->getPointerAddressSpace();
+      unsigned AS = CurPtr->getType()->getPointerAddressSpace();
       llvm::Type *AllocPtrTy = ConvertTypeForMem(AllocType)->getPointerTo(AS);
-      explicitPtr = Builder.CreateBitCast(explicitPtr, AllocPtrTy);
-      initializerElements *= getContext().getConstantArrayElementCount(CAT);
+      CurPtr = Builder.CreateBitCast(CurPtr, AllocPtrTy);
+      InitListElements *= getContext().getConstantArrayElementCount(CAT);
     }
 
-    // Enter a partial-destruction cleanup if necessary.
-    if (needsEHCleanup(dtorKind)) {
-      // In principle we could tell the cleanup where we are more
+    // Enter a partial-destruction Cleanup if necessary.
+    if (needsEHCleanup(DtorKind)) {
+      // In principle we could tell the Cleanup where we are more
       // directly, but the control flow can get so varied here that it
       // would actually be quite complex.  Therefore we go through an
       // alloca.
-      endOfInit = CreateTempAlloca(beginPtr->getType(), "array.endOfInit");
-      cleanupDominator = Builder.CreateStore(beginPtr, endOfInit);
-      pushIrregularPartialArrayCleanup(beginPtr, endOfInit, elementType,
-                                       getDestroyer(dtorKind));
-      cleanup = EHStack.stable_begin();
+      EndOfInit = CreateTempAlloca(BeginPtr->getType(), "array.init.end");
+      CleanupDominator = Builder.CreateStore(BeginPtr, EndOfInit);
+      pushIrregularPartialArrayCleanup(BeginPtr, EndOfInit, ElementType,
+                                       getDestroyer(DtorKind));
+      Cleanup = EHStack.stable_begin();
     }
 
     for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
       // Tell the cleanup that it needs to destroy up to this
       // element.  TODO: some of these stores can be trivially
       // observed to be unnecessary.
-      if (endOfInit) Builder.CreateStore(explicitPtr, endOfInit);
+      if (EndOfInit)
+        Builder.CreateStore(Builder.CreateBitCast(CurPtr, BeginPtr->getType()),
+                            EndOfInit);
+      // FIXME: If the last initializer is an incomplete initializer list for
+      // an array, and we have an array filler, we can fold together the two
+      // initialization loops.
       StoreAnyExprIntoOneUnit(*this, ILE->getInit(i),
-                              ILE->getInit(i)->getType(), explicitPtr);
-      explicitPtr = Builder.CreateConstGEP1_32(explicitPtr, 1,
-                                               "array.exp.next");
+                              ILE->getInit(i)->getType(), CurPtr);
+      CurPtr = Builder.CreateConstInBoundsGEP1_32(CurPtr, 1, "array.exp.next");
     }
 
     // The remaining elements are filled with the array filler expression.
     Init = ILE->getArrayFiller();
 
-    explicitPtr = Builder.CreateBitCast(explicitPtr, beginPtr->getType());
+    // Extract the initializer for the individual array elements by pulling
+    // out the array filler from all the nested initializer lists. This avoids
+    // generating a nested loop for the initialization.
+    while (Init && Init->getType()->isConstantArrayType()) {
+      auto *SubILE = dyn_cast<InitListExpr>(Init);
+      if (!SubILE)
+        break;
+      assert(SubILE->getNumInits() == 0 && "explicit inits in array filler?");
+      Init = SubILE->getArrayFiller();
+    }
+
+    // Switch back to initializing one base element at a time.
+    CurPtr = Builder.CreateBitCast(CurPtr, BeginPtr->getType());
   }
 
-  llvm::ConstantInt *constNum = dyn_cast<llvm::ConstantInt>(numElements);
+  // Attempt to perform zero-initialization using memset.
+  auto TryMemsetInitialization = [&]() -> bool {
+    // FIXME: If the type is a pointer-to-data-member under the Itanium ABI,
+    // we can initialize with a memset to -1.
+    if (!CGM.getTypes().isZeroInitializable(ElementType))
+      return false;
 
-  // If all elements have already been initialized, skip the whole loop.
-  if (constNum && constNum->getZExtValue() <= initializerElements) {
-    // If there was a cleanup, deactivate it.
-    if (cleanupDominator)
-      DeactivateCleanupBlock(cleanup, cleanupDominator);
+    // Optimization: since zero initialization will just set the memory
+    // to all zeroes, generate a single memset to do it in one shot.
+
+    // Subtract out the size of any elements we've already initialized.
+    auto *RemainingSize = AllocSizeWithoutCookie;
+    if (InitListElements) {
+      // We know this can't overflow; we check this when doing the allocation.
+      auto *InitializedSize = llvm::ConstantInt::get(
+          RemainingSize->getType(),
+          getContext().getTypeSizeInChars(ElementType).getQuantity() *
+              InitListElements);
+      RemainingSize = Builder.CreateSub(RemainingSize, InitializedSize);
+    }
+
+    // Create the memset.
+    CharUnits Alignment = getContext().getTypeAlignInChars(ElementType);
+    Builder.CreateMemSet(CurPtr, Builder.getInt8(0), RemainingSize,
+                         Alignment.getQuantity(), false);
+    return true;
+  };
+
+  // If all elements have already been initialized, skip any further
+  // initialization.
+  llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
+  if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
+    // If there was a Cleanup, deactivate it.
+    if (CleanupDominator)
+      DeactivateCleanupBlock(Cleanup, CleanupDominator);
     return;
   }
 
-  // Create the continuation block.
-  llvm::BasicBlock *contBB = createBasicBlock("new.loop.end");
+  assert(Init && "have trailing elements to initialize but no initializer");
+
+  // If this is a constructor call, try to optimize it out, and failing that
+  // emit a single loop to initialize all remaining elements.
+  if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
+    CXXConstructorDecl *Ctor = CCE->getConstructor();
+    if (Ctor->isTrivial()) {
+      // If new expression did not specify value-initialization, then there
+      // is no initialization.
+      if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
+        return;
+
+      if (TryMemsetInitialization())
+        return;
+    }
+
+    // Store the new Cleanup position for irregular Cleanups.
+    //
+    // FIXME: Share this cleanup with the constructor call emission rather than
+    // having it create a cleanup of its own.
+    if (EndOfInit) Builder.CreateStore(CurPtr, EndOfInit);
+
+    // Emit a constructor call loop to initialize the remaining elements.
+    if (InitListElements)
+      NumElements = Builder.CreateSub(
+          NumElements,
+          llvm::ConstantInt::get(NumElements->getType(), InitListElements));
+    EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr,
+                               CCE->arg_begin(), CCE->arg_end(),
+                               CCE->requiresZeroInitialization());
+    return;
+  }
+
+  // If this is value-initialization, we can usually use memset.
+  ImplicitValueInitExpr IVIE(ElementType);
+  if (isa<ImplicitValueInitExpr>(Init)) {
+    if (TryMemsetInitialization())
+      return;
+
+    // Switch to an ImplicitValueInitExpr for the element type. This handles
+    // only one case: multidimensional array new of pointers to members. In
+    // all other cases, we already have an initializer for the array element.
+    Init = &IVIE;
+  }
+
+  // At this point we should have found an initializer for the individual
+  // elements of the array.
+  assert(getContext().hasSameUnqualifiedType(ElementType, Init->getType()) &&
+         "got wrong type of element to initialize");
+
+  // If we have an empty initializer list, we can usually use memset.
+  if (auto *ILE = dyn_cast<InitListExpr>(Init))
+    if (ILE->getNumInits() == 0 && TryMemsetInitialization())
+      return;
+
+  // Create the loop blocks.
+  llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
+  llvm::BasicBlock *LoopBB = createBasicBlock("new.loop");
+  llvm::BasicBlock *ContBB = createBasicBlock("new.loop.end");
+
+  // Find the end of the array, hoisted out of the loop.
+  llvm::Value *EndPtr =
+    Builder.CreateInBoundsGEP(BeginPtr, NumElements, "array.end");
 
   // If the number of elements isn't constant, we have to now check if there is
   // anything left to initialize.
-  if (!constNum) {
-    llvm::BasicBlock *nonEmptyBB = createBasicBlock("new.loop.nonempty");
-    llvm::Value *isEmpty = Builder.CreateICmpEQ(explicitPtr, endPtr,
+  if (!ConstNum) {
+    llvm::Value *IsEmpty = Builder.CreateICmpEQ(CurPtr, EndPtr,
                                                 "array.isempty");
-    Builder.CreateCondBr(isEmpty, contBB, nonEmptyBB);
-    EmitBlock(nonEmptyBB);
+    Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
   }
 
   // Enter the loop.
-  llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
-  llvm::BasicBlock *loopBB = createBasicBlock("new.loop");
-
-  EmitBlock(loopBB);
+  EmitBlock(LoopBB);
 
   // Set up the current-element phi.
-  llvm::PHINode *curPtr =
-    Builder.CreatePHI(explicitPtr->getType(), 2, "array.cur");
-  curPtr->addIncoming(explicitPtr, entryBB);
+  llvm::PHINode *CurPtrPhi =
+    Builder.CreatePHI(CurPtr->getType(), 2, "array.cur");
+  CurPtrPhi->addIncoming(CurPtr, EntryBB);
+  CurPtr = CurPtrPhi;
 
-  // Store the new cleanup position for irregular cleanups.
-  if (endOfInit) Builder.CreateStore(curPtr, endOfInit);
+  // Store the new Cleanup position for irregular Cleanups.
+  if (EndOfInit) Builder.CreateStore(CurPtr, EndOfInit);
 
-  // Enter a partial-destruction cleanup if necessary.
-  if (!cleanupDominator && needsEHCleanup(dtorKind)) {
-    pushRegularPartialArrayCleanup(beginPtr, curPtr, elementType,
-                                   getDestroyer(dtorKind));
-    cleanup = EHStack.stable_begin();
-    cleanupDominator = Builder.CreateUnreachable();
+  // Enter a partial-destruction Cleanup if necessary.
+  if (!CleanupDominator && needsEHCleanup(DtorKind)) {
+    pushRegularPartialArrayCleanup(BeginPtr, CurPtr, ElementType,
+                                   getDestroyer(DtorKind));
+    Cleanup = EHStack.stable_begin();
+    CleanupDominator = Builder.CreateUnreachable();
   }
 
   // Emit the initializer into this element.
-  StoreAnyExprIntoOneUnit(*this, Init, E->getAllocatedType(), curPtr);
+  StoreAnyExprIntoOneUnit(*this, Init, Init->getType(), CurPtr);
 
-  // Leave the cleanup if we entered one.
-  if (cleanupDominator) {
-    DeactivateCleanupBlock(cleanup, cleanupDominator);
-    cleanupDominator->eraseFromParent();
+  // Leave the Cleanup if we entered one.
+  if (CleanupDominator) {
+    DeactivateCleanupBlock(Cleanup, CleanupDominator);
+    CleanupDominator->eraseFromParent();
   }
 
-  // FIXME: The code below intends to initialize the individual array base
-  // elements, one at a time - but when dealing with multi-dimensional arrays -
-  // the pointer arithmetic can get confused - so the fix below entails casting
-  // to the allocated type to ensure that we get the pointer arithmetic right.
-  // It seems like the right approach here, it to really initialize the
-  // individual array base elements one at a time since it'll generate less
-  // code. I think the problem is that the wrong type is being passed into
-  // StoreAnyExprIntoOneUnit, but directly fixing that doesn't really work,
-  // because the Init expression has the wrong type at this point.
-  // So... this is ok for a quick fix, but we can and should do a lot better
-  // here long-term.
-
   // Advance to the next element by adjusting the pointer type as necessary.
-  // For new int[10][20][30], alloc type is int[20][30], base type is 'int'.
-  QualType AllocType = E->getAllocatedType();
-  llvm::Type *AllocPtrTy = ConvertTypeForMem(AllocType)->getPointerTo(
-      curPtr->getType()->getPointerAddressSpace());
-  llvm::Value *curPtrAllocTy = Builder.CreateBitCast(curPtr, AllocPtrTy);
-  llvm::Value *nextPtrAllocTy =
-      Builder.CreateConstGEP1_32(curPtrAllocTy, 1, "array.next");
-  // Cast it back to the base type so that we can compare it to the endPtr.
-  llvm::Value *nextPtr =
-      Builder.CreateBitCast(nextPtrAllocTy, endPtr->getType());
+  llvm::Value *NextPtr =
+      Builder.CreateConstInBoundsGEP1_32(CurPtr, 1, "array.next");
+
   // Check whether we've gotten to the end of the array and, if so,
   // exit the loop.
-  llvm::Value *isEnd = Builder.CreateICmpEQ(nextPtr, endPtr, "array.atend");
-  Builder.CreateCondBr(isEnd, contBB, loopBB);
-  curPtr->addIncoming(nextPtr, Builder.GetInsertBlock());
+  llvm::Value *IsEnd = Builder.CreateICmpEQ(NextPtr, EndPtr, "array.atend");
+  Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
+  CurPtrPhi->addIncoming(NextPtr, Builder.GetInsertBlock());
 
-  EmitBlock(contBB);
+  EmitBlock(ContBB);
 }
 
-static void EmitZeroMemSet(CodeGenFunction &CGF, QualType T,
-                           llvm::Value *NewPtr, llvm::Value *Size) {
-  CGF.EmitCastToVoidPtr(NewPtr);
-  CharUnits Alignment = CGF.getContext().getTypeAlignInChars(T);
-  CGF.Builder.CreateMemSet(NewPtr, CGF.Builder.getInt8(0), Size,
-                           Alignment.getQuantity(), false);
-}
-                       
 static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
                                QualType ElementType,
                                llvm::Value *NewPtr,
                                llvm::Value *NumElements,
                                llvm::Value *AllocSizeWithoutCookie) {
-  const Expr *Init = E->getInitializer();
-  if (E->isArray()) {
-    if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)){
-      CXXConstructorDecl *Ctor = CCE->getConstructor();
-      if (Ctor->isTrivial()) {
-        // If new expression did not specify value-initialization, then there
-        // is no initialization.
-        if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
-          return;
-      
-        if (CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
-          // Optimization: since zero initialization will just set the memory
-          // to all zeroes, generate a single memset to do it in one shot.
-          EmitZeroMemSet(CGF, ElementType, NewPtr, AllocSizeWithoutCookie);
-          return;
-        }
-      }
-
-      CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
-                                     CCE->arg_begin(),  CCE->arg_end(),
-                                     CCE->requiresZeroInitialization());
-      return;
-    } else if (Init && isa<ImplicitValueInitExpr>(Init) &&
-               CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
-      // Optimization: since zero initialization will just set the memory
-      // to all zeroes, generate a single memset to do it in one shot.
-      EmitZeroMemSet(CGF, ElementType, NewPtr, AllocSizeWithoutCookie);
-      return;
-    }
-    CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
-    return;
-  }
-
-  if (!Init)
-    return;
-
-  StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr);
+  if (E->isArray())
+    CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements,
+                                AllocSizeWithoutCookie);
+  else if (const Expr *Init = E->getInitializer())
+    StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr);
 }
 
 /// Emit a call to an operator new or operator delete function, as implicitly
@@ -987,6 +1029,24 @@
   return RV;
 }
 
+RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
+                                                 const Expr *Arg,
+                                                 bool IsDelete) {
+  CallArgList Args;
+  const Stmt *ArgS = Arg;
+  EmitCallArgs(Args, *Type->param_type_begin(),
+               ConstExprIterator(&ArgS), ConstExprIterator(&ArgS + 1));
+  // Find the allocation or deallocation function that we're calling.
+  ASTContext &Ctx = getContext();
+  DeclarationName Name = Ctx.DeclarationNames
+      .getCXXOperatorName(IsDelete ? OO_Delete : OO_New);
+  for (auto *Decl : Ctx.getTranslationUnitDecl()->lookup(Name))
+    if (auto *FD = dyn_cast<FunctionDecl>(Decl))
+      if (Ctx.hasSameType(FD->getType(), QualType(Type, 0)))
+        return EmitNewDeleteCall(*this, cast<FunctionDecl>(Decl), Type, Args);
+  llvm_unreachable("predeclared global operator new/delete is missing");
+}
+
 namespace {
   /// A cleanup to call the given 'operator delete' function upon
   /// abnormal exit from a new expression.
@@ -1555,21 +1615,7 @@
   EmitBlock(DeleteEnd);
 }
 
-static llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) {
-  // void __cxa_bad_typeid();
-  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
-  
-  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
-}
-
-static void EmitBadTypeidCall(CodeGenFunction &CGF) {
-  llvm::Value *Fn = getBadTypeidFn(CGF);
-  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
-  CGF.Builder.CreateUnreachable();
-}
-
-static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF,
-                                         const Expr *E, 
+static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
                                          llvm::Type *StdTypeInfoPtrTy) {
   // Get the vtable pointer.
   llvm::Value *ThisPtr = CGF.EmitLValue(E).getAddress();
@@ -1578,28 +1624,27 @@
   //   If the glvalue expression is obtained by applying the unary * operator to
   //   a pointer and the pointer is a null pointer value, the typeid expression
   //   throws the std::bad_typeid exception.
-  if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParens())) {
-    if (UO->getOpcode() == UO_Deref) {
-      llvm::BasicBlock *BadTypeidBlock = 
+  bool IsDeref = false;
+  if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParens()))
+    if (UO->getOpcode() == UO_Deref)
+      IsDeref = true;
+
+  QualType SrcRecordTy = E->getType();
+  if (CGF.CGM.getCXXABI().shouldTypeidBeNullChecked(IsDeref, SrcRecordTy)) {
+    llvm::BasicBlock *BadTypeidBlock =
         CGF.createBasicBlock("typeid.bad_typeid");
-      llvm::BasicBlock *EndBlock =
-        CGF.createBasicBlock("typeid.end");
+    llvm::BasicBlock *EndBlock = CGF.createBasicBlock("typeid.end");
 
-      llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr);
-      CGF.Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock);
+    llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr);
+    CGF.Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock);
 
-      CGF.EmitBlock(BadTypeidBlock);
-      EmitBadTypeidCall(CGF);
-      CGF.EmitBlock(EndBlock);
-    }
+    CGF.EmitBlock(BadTypeidBlock);
+    CGF.CGM.getCXXABI().EmitBadTypeidCall(CGF);
+    CGF.EmitBlock(EndBlock);
   }
 
-  llvm::Value *Value = CGF.GetVTablePtr(ThisPtr, 
-                                        StdTypeInfoPtrTy->getPointerTo());
-
-  // Load the type info.
-  Value = CGF.Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
-  return CGF.Builder.CreateLoad(Value);
+  return CGF.CGM.getCXXABI().EmitTypeid(CGF, SrcRecordTy, ThisPtr,
+                                        StdTypeInfoPtrTy);
 }
 
 llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
@@ -1626,173 +1671,6 @@
                                StdTypeInfoPtrTy);
 }
 
-static llvm::Constant *getDynamicCastFn(CodeGenFunction &CGF) {
-  // void *__dynamic_cast(const void *sub,
-  //                      const abi::__class_type_info *src,
-  //                      const abi::__class_type_info *dst,
-  //                      std::ptrdiff_t src2dst_offset);
-  
-  llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
-  llvm::Type *PtrDiffTy = 
-    CGF.ConvertType(CGF.getContext().getPointerDiffType());
-
-  llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
-
-  llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
-
-  // Mark the function as nounwind readonly.
-  llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
-                                            llvm::Attribute::ReadOnly };
-  llvm::AttributeSet Attrs = llvm::AttributeSet::get(
-      CGF.getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
-
-  return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs);
-}
-
-static llvm::Constant *getBadCastFn(CodeGenFunction &CGF) {
-  // void __cxa_bad_cast();
-  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
-  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast");
-}
-
-static void EmitBadCastCall(CodeGenFunction &CGF) {
-  llvm::Value *Fn = getBadCastFn(CGF);
-  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
-  CGF.Builder.CreateUnreachable();
-}
-
-/// \brief Compute the src2dst_offset hint as described in the
-/// Itanium C++ ABI [2.9.7]
-static CharUnits computeOffsetHint(ASTContext &Context,
-                                   const CXXRecordDecl *Src,
-                                   const CXXRecordDecl *Dst) {
-  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
-                     /*DetectVirtual=*/false);
-
-  // If Dst is not derived from Src we can skip the whole computation below and
-  // return that Src is not a public base of Dst.  Record all inheritance paths.
-  if (!Dst->isDerivedFrom(Src, Paths))
-    return CharUnits::fromQuantity(-2ULL);
-
-  unsigned NumPublicPaths = 0;
-  CharUnits Offset;
-
-  // Now walk all possible inheritance paths.
-  for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end();
-       I != E; ++I) {
-    if (I->Access != AS_public) // Ignore non-public inheritance.
-      continue;
-
-    ++NumPublicPaths;
-
-    for (CXXBasePath::iterator J = I->begin(), JE = I->end(); J != JE; ++J) {
-      // If the path contains a virtual base class we can't give any hint.
-      // -1: no hint.
-      if (J->Base->isVirtual())
-        return CharUnits::fromQuantity(-1ULL);
-
-      if (NumPublicPaths > 1) // Won't use offsets, skip computation.
-        continue;
-
-      // Accumulate the base class offsets.
-      const ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
-      Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
-    }
-  }
-
-  // -2: Src is not a public base of Dst.
-  if (NumPublicPaths == 0)
-    return CharUnits::fromQuantity(-2ULL);
-
-  // -3: Src is a multiple public base type but never a virtual base type.
-  if (NumPublicPaths > 1)
-    return CharUnits::fromQuantity(-3ULL);
-
-  // Otherwise, the Src type is a unique public nonvirtual base type of Dst.
-  // Return the offset of Src from the origin of Dst.
-  return Offset;
-}
-
-static llvm::Value *
-EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
-                    QualType SrcTy, QualType DestTy,
-                    llvm::BasicBlock *CastEnd) {
-  llvm::Type *PtrDiffLTy = 
-    CGF.ConvertType(CGF.getContext().getPointerDiffType());
-  llvm::Type *DestLTy = CGF.ConvertType(DestTy);
-
-  if (const PointerType *PTy = DestTy->getAs<PointerType>()) {
-    if (PTy->getPointeeType()->isVoidType()) {
-      // C++ [expr.dynamic.cast]p7:
-      //   If T is "pointer to cv void," then the result is a pointer to the
-      //   most derived object pointed to by v.
-
-      // Get the vtable pointer.
-      llvm::Value *VTable = CGF.GetVTablePtr(Value, PtrDiffLTy->getPointerTo());
-
-      // Get the offset-to-top from the vtable.
-      llvm::Value *OffsetToTop = 
-        CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
-      OffsetToTop = CGF.Builder.CreateLoad(OffsetToTop, "offset.to.top");
-
-      // Finally, add the offset to the pointer.
-      Value = CGF.EmitCastToVoidPtr(Value);
-      Value = CGF.Builder.CreateInBoundsGEP(Value, OffsetToTop);
-
-      return CGF.Builder.CreateBitCast(Value, DestLTy);
-    }
-  }
-
-  QualType SrcRecordTy;
-  QualType DestRecordTy;
-  
-  if (const PointerType *DestPTy = DestTy->getAs<PointerType>()) {
-    SrcRecordTy = SrcTy->castAs<PointerType>()->getPointeeType();
-    DestRecordTy = DestPTy->getPointeeType();
-  } else {
-    SrcRecordTy = SrcTy;
-    DestRecordTy = DestTy->castAs<ReferenceType>()->getPointeeType();
-  }
-
-  assert(SrcRecordTy->isRecordType() && "source type must be a record type!");
-  assert(DestRecordTy->isRecordType() && "dest type must be a record type!");
-
-  llvm::Value *SrcRTTI =
-    CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
-  llvm::Value *DestRTTI =
-    CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
-
-  // Compute the offset hint.
-  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
-  const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();
-  llvm::Value *OffsetHint =
-    llvm::ConstantInt::get(PtrDiffLTy,
-                           computeOffsetHint(CGF.getContext(), SrcDecl,
-                                             DestDecl).getQuantity());
-
-  // Emit the call to __dynamic_cast.
-  Value = CGF.EmitCastToVoidPtr(Value);
-
-  llvm::Value *args[] = { Value, SrcRTTI, DestRTTI, OffsetHint };
-  Value = CGF.EmitNounwindRuntimeCall(getDynamicCastFn(CGF), args);
-  Value = CGF.Builder.CreateBitCast(Value, DestLTy);
-
-  /// C++ [expr.dynamic.cast]p9:
-  ///   A failed cast to reference type throws std::bad_cast
-  if (DestTy->isReferenceType()) {
-    llvm::BasicBlock *BadCastBlock = 
-      CGF.createBasicBlock("dynamic_cast.bad_cast");
-
-    llvm::Value *IsNull = CGF.Builder.CreateIsNull(Value);
-    CGF.Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
-
-    CGF.EmitBlock(BadCastBlock);
-    EmitBadCastCall(CGF);
-  }
-
-  return Value;
-}
-
 static llvm::Value *EmitDynamicCastToNull(CodeGenFunction &CGF,
                                           QualType DestTy) {
   llvm::Type *DestLTy = CGF.ConvertType(DestTy);
@@ -1801,7 +1679,8 @@
 
   /// C++ [expr.dynamic.cast]p9:
   ///   A failed cast to reference type throws std::bad_cast
-  EmitBadCastCall(CGF);
+  if (!CGF.CGM.getCXXABI().EmitBadCastCall(CGF))
+    return nullptr;
 
   CGF.EmitBlock(CGF.createBasicBlock("dynamic_cast.end"));
   return llvm::UndefValue::get(DestLTy);
@@ -1812,14 +1691,37 @@
   QualType DestTy = DCE->getTypeAsWritten();
 
   if (DCE->isAlwaysNull())
-    return EmitDynamicCastToNull(*this, DestTy);
+    if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy))
+      return T;
 
   QualType SrcTy = DCE->getSubExpr()->getType();
 
+  // C++ [expr.dynamic.cast]p7:
+  //   If T is "pointer to cv void," then the result is a pointer to the most
+  //   derived object pointed to by v.
+  const PointerType *DestPTy = DestTy->getAs<PointerType>();
+
+  bool isDynamicCastToVoid;
+  QualType SrcRecordTy;
+  QualType DestRecordTy;
+  if (DestPTy) {
+    isDynamicCastToVoid = DestPTy->getPointeeType()->isVoidType();
+    SrcRecordTy = SrcTy->castAs<PointerType>()->getPointeeType();
+    DestRecordTy = DestPTy->getPointeeType();
+  } else {
+    isDynamicCastToVoid = false;
+    SrcRecordTy = SrcTy;
+    DestRecordTy = DestTy->castAs<ReferenceType>()->getPointeeType();
+  }
+
+  assert(SrcRecordTy->isRecordType() && "source type must be a record type!");
+
   // C++ [expr.dynamic.cast]p4: 
   //   If the value of v is a null pointer value in the pointer case, the result
   //   is the null pointer value of type T.
-  bool ShouldNullCheckSrcValue = SrcTy->isPointerType();
+  bool ShouldNullCheckSrcValue =
+      CGM.getCXXABI().shouldDynamicCastCallBeNullChecked(SrcTy->isPointerType(),
+                                                         SrcRecordTy);
 
   llvm::BasicBlock *CastNull = nullptr;
   llvm::BasicBlock *CastNotNull = nullptr;
@@ -1834,7 +1736,15 @@
     EmitBlock(CastNotNull);
   }
 
-  Value = EmitDynamicCastCall(*this, Value, SrcTy, DestTy, CastEnd);
+  if (isDynamicCastToVoid) {
+    Value = CGM.getCXXABI().EmitDynamicCastToVoid(*this, Value, SrcRecordTy,
+                                                  DestTy);
+  } else {
+    assert(DestRecordTy->isRecordType() &&
+           "destination type must be a record type!");
+    Value = CGM.getCXXABI().EmitDynamicCastCall(*this, Value, SrcRecordTy,
+                                                DestTy, DestRecordTy, CastEnd);
+  }
 
   if (ShouldNullCheckSrcValue) {
     EmitBranch(CastEnd);
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 1ee3ce8..1be7b42 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -358,7 +358,10 @@
   Value *VisitExprWithCleanups(ExprWithCleanups *E) {
     CGF.enterFullExpression(E);
     CodeGenFunction::RunCleanupsScope Scope(CGF);
-    return Visit(E->getSubExpr());
+    auto *V = Visit(E->getSubExpr());
+    if (CGDebugInfo *DI = CGF.getDebugInfo())
+      DI->EmitLocation(Builder, E->getLocEnd(), false);
+    return V;
   }
   Value *VisitCXXNewExpr(const CXXNewExpr *E) {
     return CGF.EmitCXXNewExpr(E);
@@ -940,9 +943,8 @@
                                                   MTy->getNumElements());
     Value* NewV = llvm::UndefValue::get(RTy);
     for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
-      Value *IIndx = Builder.getInt32(i);
+      Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i);
       Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx");
-      Indx = Builder.CreateZExt(Indx, CGF.Int32Ty, "idx_zext");
 
       Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");
       NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins");
@@ -1073,8 +1075,6 @@
   if (CGF.SanOpts->ArrayBounds)
     CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);
 
-  bool IdxSigned = IdxTy->isSignedIntegerOrEnumerationType();
-  Idx = Builder.CreateIntCast(Idx, CGF.Int32Ty, IdxSigned, "vecidxcast");
   return Builder.CreateExtractElement(Base, Idx, "vecext");
 }
 
@@ -1328,7 +1328,7 @@
 
     // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is
     // performed and the object is not of the derived type.
-    if (CGF.SanitizePerformTypeCheck)
+    if (CGF.sanitizePerformTypeCheck())
       CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(),
                         Derived, DestTy->getPointeeType());
 
@@ -1618,12 +1618,11 @@
 
     // Note that signed integer inc/dec with width less than int can't
     // overflow because of promotion rules; we're just eliding a few steps here.
-    if (value->getType()->getPrimitiveSizeInBits() >=
-            CGF.IntTy->getBitWidth() &&
-        type->isSignedIntegerOrEnumerationType()) {
+    bool CanOverflow = value->getType()->getIntegerBitWidth() >=
+                       CGF.IntTy->getIntegerBitWidth();
+    if (CanOverflow && type->isSignedIntegerOrEnumerationType()) {
       value = EmitAddConsiderOverflowBehavior(E, value, amt, isInc);
-    } else if (value->getType()->getPrimitiveSizeInBits() >=
-               CGF.IntTy->getBitWidth() && type->isUnsignedIntegerType() &&
+    } else if (CanOverflow && type->isUnsignedIntegerType() &&
                CGF.SanOpts->UnsignedIntegerOverflow) {
       BinOpInfo BinOp;
       BinOp.LHS = value;
@@ -1735,11 +1734,12 @@
   if (atomicPHI) {
     llvm::BasicBlock *opBB = Builder.GetInsertBlock();
     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
-    llvm::Value *old = Builder.CreateAtomicCmpXchg(
+    llvm::Value *pair = Builder.CreateAtomicCmpXchg(
         LV.getAddress(), atomicPHI, CGF.EmitToMemory(value, type),
         llvm::SequentiallyConsistent, llvm::SequentiallyConsistent);
+    llvm::Value *old = Builder.CreateExtractValue(pair, 0);
+    llvm::Value *success = Builder.CreateExtractValue(pair, 1);
     atomicPHI->addIncoming(old, opBB);
-    llvm::Value *success = Builder.CreateICmpEQ(old, atomicPHI);
     Builder.CreateCondBr(success, contBB, opBB);
     Builder.SetInsertPoint(contBB);
     return isPre ? value : input;
@@ -2078,11 +2078,12 @@
   if (atomicPHI) {
     llvm::BasicBlock *opBB = Builder.GetInsertBlock();
     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
-    llvm::Value *old = Builder.CreateAtomicCmpXchg(
+    llvm::Value *pair = Builder.CreateAtomicCmpXchg(
         LHSLV.getAddress(), atomicPHI, CGF.EmitToMemory(Result, LHSTy),
         llvm::SequentiallyConsistent, llvm::SequentiallyConsistent);
+    llvm::Value *old = Builder.CreateExtractValue(pair, 0);
+    llvm::Value *success = Builder.CreateExtractValue(pair, 1);
     atomicPHI->addIncoming(old, opBB);
-    llvm::Value *success = Builder.CreateICmpEQ(old, atomicPHI);
     Builder.CreateCondBr(success, contBB, opBB);
     Builder.SetInsertPoint(contBB);
     return LHSLV;
diff --git a/lib/CodeGen/CGLoopInfo.cpp b/lib/CodeGen/CGLoopInfo.cpp
index 7b154b2..1bc6d20 100644
--- a/lib/CodeGen/CGLoopInfo.cpp
+++ b/lib/CodeGen/CGLoopInfo.cpp
@@ -31,7 +31,7 @@
 
   // Setting vectorizer.width
   if (Attrs.VectorizerWidth > 0) {
-    Value *Vals[] = { MDString::get(Ctx, "llvm.vectorizer.width"),
+    Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.width"),
                       ConstantInt::get(Type::getInt32Ty(Ctx),
                                        Attrs.VectorizerWidth) };
     Args.push_back(MDNode::get(Ctx, Vals));
@@ -39,7 +39,7 @@
 
   // Setting vectorizer.unroll
   if (Attrs.VectorizerUnroll > 0) {
-    Value *Vals[] = { MDString::get(Ctx, "llvm.vectorizer.unroll"),
+    Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.unroll"),
                       ConstantInt::get(Type::getInt32Ty(Ctx),
                                        Attrs.VectorizerUnroll) };
     Args.push_back(MDNode::get(Ctx, Vals));
@@ -47,7 +47,7 @@
 
   // Setting vectorizer.enable
   if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) {
-    Value *Vals[] = { MDString::get(Ctx, "llvm.vectorizer.enable"),
+    Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.enable"),
                       ConstantInt::get(Type::getInt1Ty(Ctx),
                                        (Attrs.VectorizerEnable ==
                                         LoopAttributes::VecEnable)) };
diff --git a/lib/CodeGen/CGLoopInfo.h b/lib/CodeGen/CGLoopInfo.h
index f4a8dca..2461368 100644
--- a/lib/CodeGen/CGLoopInfo.h
+++ b/lib/CodeGen/CGLoopInfo.h
@@ -37,16 +37,16 @@
   /// \brief Generate llvm.loop.parallel metadata for loads and stores.
   bool IsParallel;
 
-  /// \brief Values of llvm.vectorizer.enable metadata.
+  /// \brief Values of llvm.loop.vectorize.enable metadata.
   enum LVEnableState { VecUnspecified, VecEnable, VecDisable };
 
-  /// \brief llvm.vectorizer.enable
+  /// \brief llvm.loop.vectorize.enable
   LVEnableState VectorizerEnable;
 
-  /// \brief llvm.vectorizer.width
+  /// \brief llvm.loop.vectorize.width
   unsigned VectorizerWidth;
 
-  /// \brief llvm.vectorizer.unroll
+  /// \brief llvm.loop.vectorize.unroll
   unsigned VectorizerUnroll;
 };
 
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 3ca0378..619a66a 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -237,9 +237,8 @@
       NameAndAttributes += TypeStr;
       NameAndAttributes += '\0';
       NameAndAttributes += PD->getNameAsString();
-      NameAndAttributes += '\0';
       return llvm::ConstantExpr::getGetElementPtr(
-          CGM.GetAddrOfConstantString(NameAndAttributes), Zeros);
+          CGM.GetAddrOfConstantCString(NameAndAttributes), Zeros);
     }
     return MakeConstantString(PD->getNameAsString());
   }
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 95503cc..88ad7f1 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1018,14 +1018,12 @@
   /// \param Name - The variable name.
   /// \param Init - The variable initializer; this is also used to
   /// define the type of the variable.
-  /// \param Section - The section the variable should go into, or 0.
+  /// \param Section - The section the variable should go into, or empty.
   /// \param Align - The alignment for the variable, or 0.
   /// \param AddToUsed - Whether the variable should be added to
   /// "llvm.used".
-  llvm::GlobalVariable *CreateMetadataVar(Twine Name,
-                                          llvm::Constant *Init,
-                                          const char *Section,
-                                          unsigned Align,
+  llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init,
+                                          StringRef Section, unsigned Align,
                                           bool AddToUsed);
 
   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
@@ -1391,7 +1389,7 @@
   /// EmitMetaClassRef - Return a Value * of the address of _class_t
   /// meta-data
   llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
-                                const ObjCInterfaceDecl *ID);
+                                const ObjCInterfaceDecl *ID, bool Weak);
 
   /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
   /// the given ivar.
@@ -2723,9 +2721,8 @@
     llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
 
   // No special section, but goes in llvm.used
-  return CreateMetadataVar("\01l_OBJC_PROTOCOLEXT_" + PD->getName(),
-                           Init,
-                           nullptr, 0, true);
+  return CreateMetadataVar("\01l_OBJC_PROTOCOLEXT_" + PD->getName(), Init,
+                           StringRef(), 0, true);
 }
 
 /*
@@ -2858,11 +2855,9 @@
                                              MethodTypes.size());
   llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
 
-  llvm::GlobalVariable *GV = 
-    CreateMetadataVar(Name, Init,
-                      (ObjCABI == 2) ? "__DATA, __objc_const" : nullptr,
-                      (ObjCABI == 2) ? 8 : 4,
-                      true);
+  llvm::GlobalVariable *GV = CreateMetadataVar(
+      Name, Init, (ObjCABI == 2) ? "__DATA, __objc_const" : StringRef(),
+      (ObjCABI == 2) ? 8 : 4, true);
   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
 }
 
@@ -3395,18 +3390,17 @@
   return Method;
 }
 
-llvm::GlobalVariable *
-CGObjCCommonMac::CreateMetadataVar(Twine Name,
-                                   llvm::Constant *Init,
-                                   const char *Section,
-                                   unsigned Align,
-                                   bool AddToUsed) {
+llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
+                                                         llvm::Constant *Init,
+                                                         StringRef Section,
+                                                         unsigned Align,
+                                                         bool AddToUsed) {
   llvm::Type *Ty = Init->getType();
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(CGM.getModule(), Ty, false,
                              llvm::GlobalValue::PrivateLinkage, Init, Name);
   assertPrivateName(GV);
-  if (Section)
+  if (!Section.empty())
     GV->setSection(Section);
   if (Align)
     GV->setAlignment(Align);
@@ -4457,13 +4451,12 @@
   llvm::GlobalVariable *&Entry = ClassNames[Ident];
 
   if (!Entry)
-    Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
-                              llvm::ConstantDataArray::getString(VMContext,
-                                                         Ident->getNameStart()),
-                              ((ObjCABI == 2) ?
-                               "__TEXT,__objc_classname,cstring_literals" :
-                               "__TEXT,__cstring,cstring_literals"),
-                              1, true);
+    Entry = CreateMetadataVar(
+        "\01L_OBJC_CLASS_NAME_",
+        llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
+        ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
+                        : "__TEXT,__cstring,cstring_literals"),
+        1, true);
 
   return getConstantGEP(VMContext, Entry, 0, 0);
 }
@@ -4926,11 +4919,10 @@
   llvm::GlobalVariable *&Entry = PropertyNames[Ident];
 
   if (!Entry)
-    Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
-                        llvm::ConstantDataArray::getString(VMContext,
-                                                       Ident->getNameStart()),
-                              "__TEXT,__cstring,cstring_literals",
-                              1, true);
+    Entry = CreateMetadataVar(
+        "\01L_OBJC_PROP_NAME_ATTR_",
+        llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
+        "__TEXT,__cstring,cstring_literals", 1, true);
 
   return getConstantGEP(VMContext, Entry, 0, 0);
 }
@@ -6710,13 +6702,15 @@
 /// meta-data
 ///
 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
-                                                      const ObjCInterfaceDecl *ID) {
+                                                      const ObjCInterfaceDecl *ID,
+                                                      bool Weak) {
   llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
   if (!Entry) {
 
     std::string MetaClassName(getMetaclassSymbolPrefix() +
                               ID->getNameAsString());
-    llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
+    llvm::GlobalVariable *MetaClassGV =
+      GetClassGlobal(MetaClassName, Weak);
     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
                                      false, llvm::GlobalValue::PrivateLinkage,
                                      MetaClassGV,
@@ -6774,7 +6768,8 @@
   // If this is a class message the metaclass is passed as the target.
   llvm::Value *Target;
   if (IsClassMessage)
-      Target = EmitMetaClassRef(CGF, Class);
+      Target = EmitMetaClassRef(CGF, Class,
+                                (isCategoryImpl && Class->isWeakImported()));
   else
     Target = EmitSuperClassRef(CGF, Class);
 
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
index 1a5db9b..3d013da 100644
--- a/lib/CodeGen/CGObjCRuntime.cpp
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -149,7 +149,7 @@
     const VarDecl *Variable;
     const Stmt *Body;
     llvm::BasicBlock *Block;
-    llvm::Value *TypeInfo;
+    llvm::Constant *TypeInfo;
   };
 
   struct CallObjCEndCatch : EHScopeStack::Cleanup {
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index da86e2b..12a3a77 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -19,7 +19,7 @@
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/Value.h"
 #include "llvm/Support/raw_ostream.h"
-#include <assert.h>
+#include <cassert>
 
 using namespace clang;
 using namespace CodeGen;
@@ -31,8 +31,8 @@
       CGM.Int32Ty /* reserved_2 */, CGM.Int32Ty /* reserved_3 */,
       CGM.Int8PtrTy /* psource */, NULL);
   // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
-  llvm::Type *MicroParams[] = { llvm::PointerType::getUnqual(CGM.Int32Ty),
-                                llvm::PointerType::getUnqual(CGM.Int32Ty) };
+  llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
+                               llvm::PointerType::getUnqual(CGM.Int32Ty)};
   Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
 }
 
@@ -57,9 +57,9 @@
     DefaultOpenMPLocation->setLinkage(llvm::GlobalValue::PrivateLinkage);
 
     llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true);
-    llvm::Constant *Values[] = { Zero,
-                                 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
-                                 Zero, Zero, DefaultOpenMPPSource };
+    llvm::Constant *Values[] = {Zero,
+                                llvm::ConstantInt::get(CGM.Int32Ty, Flags),
+                                Zero, Zero, DefaultOpenMPPSource};
     llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values);
     DefaultOpenMPLocation->setInitializer(Init);
     return DefaultOpenMPLocation;
@@ -98,19 +98,24 @@
   llvm::Value *PSource =
       CGF.Builder.CreateConstInBoundsGEP2_32(LocValue, 0, IdentField_PSource);
 
-  SmallString<128> Buffer2;
-  llvm::raw_svector_ostream OS2(Buffer2);
-  // Build debug location
-  PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
-  OS2 << ";" << PLoc.getFilename() << ";";
-  if (const FunctionDecl *FD =
-          dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) {
-    OS2 << FD->getQualifiedNameAsString();
+  auto OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
+  if (OMPDebugLoc == nullptr) {
+    SmallString<128> Buffer2;
+    llvm::raw_svector_ostream OS2(Buffer2);
+    // Build debug location
+    PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
+    OS2 << ";" << PLoc.getFilename() << ";";
+    if (const FunctionDecl *FD =
+            dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) {
+      OS2 << FD->getQualifiedNameAsString();
+    }
+    OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
+    OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
+    OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
   }
-  OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
   // *psource = ";<File>;<Function>;<Line>;<Column>;;";
-  CGF.Builder.CreateStore(CGF.Builder.CreateGlobalStringPtr(OS2.str()),
-                          PSource);
+  CGF.Builder.CreateStore(OMPDebugLoc, PSource);
+
   return LocValue;
 }
 
@@ -126,7 +131,7 @@
     // Generate "int32 .kmpc_global_thread_num.addr;"
     CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
     CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
-    llvm::Value *Args[] = { EmitOpenMPUpdateLocation(CGF, Loc) };
+    llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc)};
     GTid = CGF.EmitRuntimeCall(
         CreateRuntimeFunction(OMPRTL__kmpc_global_thread_num), Args);
     OpenMPGtidMap[CGF.CurFn] = GTid;
@@ -157,8 +162,8 @@
   case OMPRTL__kmpc_fork_call: {
     // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
     // microtask, ...);
-    llvm::Type *TypeParams[] = { getIdentTyPointerTy(), CGM.Int32Ty,
-                                 getKmpc_MicroPointerTy() };
+    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
+                                getKmpc_MicroPointerTy()};
     llvm::FunctionType *FnTy =
         llvm::FunctionType::get(CGM.VoidTy, TypeParams, true);
     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
@@ -166,7 +171,7 @@
   }
   case OMPRTL__kmpc_global_thread_num: {
     // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
-    llvm::Type *TypeParams[] = { getIdentTyPointerTy() };
+    llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
     llvm::FunctionType *FnTy =
         llvm::FunctionType::get(CGM.Int32Ty, TypeParams, false);
     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
index 06103cf..862e8a1 100644
--- a/lib/CodeGen/CGOpenMPRuntime.h
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -31,7 +31,7 @@
 class StructType;
 class Type;
 class Value;
-}
+} // namespace llvm
 
 namespace clang {
 
@@ -121,6 +121,9 @@
     IdentField_PSource
   };
   llvm::StructType *IdentTy;
+  /// \brief Map for Sourcelocation and OpenMP runtime library debug locations.
+  typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy;
+  OpenMPDebugLocMapTy OpenMPDebugLocMap;
   /// \brief The type for a microtask which gets passed to __kmpc_fork_call().
   /// Original representation is:
   /// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...);
@@ -133,7 +136,7 @@
   OpenMPGtidMapTy OpenMPGtidMap;
 
 public:
-  CGOpenMPRuntime(CodeGenModule &CGM);
+  explicit CGOpenMPRuntime(CodeGenModule &CGM);
   ~CGOpenMPRuntime() {}
 
   /// \brief Cleans up references to the objects in finished function.
@@ -168,7 +171,7 @@
   /// \return Specified function.
   llvm::Constant *CreateRuntimeFunction(OpenMPRTLFunction Function);
 };
-}
-}
+} // namespace CodeGen
+} // namespace clang
 
 #endif
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
deleted file mode 100644
index 4ca315c..0000000
--- a/lib/CodeGen/CGRTTI.cpp
+++ /dev/null
@@ -1,998 +0,0 @@
-//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation of RTTI descriptors.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenModule.h"
-#include "CGCXXABI.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/Type.h"
-#include "clang/Frontend/CodeGenOptions.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
-class ItaniumRTTIBuilder {
-  CodeGenModule &CGM;  // Per-module state.
-  llvm::LLVMContext &VMContext;
-  
-  /// Fields - The fields of the RTTI descriptor currently being built.
-  SmallVector<llvm::Constant *, 16> Fields;
-
-  /// GetAddrOfTypeName - Returns the mangled type name of the given type.
-  llvm::GlobalVariable *
-  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
-
-  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 
-  /// descriptor of the given type.
-  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
-  
-  /// BuildVTablePointer - Build the vtable pointer for the given type.
-  void BuildVTablePointer(const Type *Ty);
-  
-  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
-  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
-  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
-  
-  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
-  /// classes with bases that do not satisfy the abi::__si_class_type_info 
-  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
-  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
-  
-  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
-  /// for pointer types.
-  void BuildPointerTypeInfo(QualType PointeeTy);
-
-  /// BuildObjCObjectTypeInfo - Build the appropriate kind of
-  /// type_info for an object type.
-  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
-  
-  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
-  /// struct, used for member pointer types.
-  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
-  
-public:
-  ItaniumRTTIBuilder(CodeGenModule &CGM) : CGM(CGM), 
-    VMContext(CGM.getModule().getContext()) { }
-
-  // Pointer type info flags.
-  enum {
-    /// PTI_Const - Type has const qualifier.
-    PTI_Const = 0x1,
-    
-    /// PTI_Volatile - Type has volatile qualifier.
-    PTI_Volatile = 0x2,
-    
-    /// PTI_Restrict - Type has restrict qualifier.
-    PTI_Restrict = 0x4,
-    
-    /// PTI_Incomplete - Type is incomplete.
-    PTI_Incomplete = 0x8,
-    
-    /// PTI_ContainingClassIncomplete - Containing class is incomplete.
-    /// (in pointer to member).
-    PTI_ContainingClassIncomplete = 0x10
-  };
-  
-  // VMI type info flags.
-  enum {
-    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
-    VMI_NonDiamondRepeat = 0x1,
-    
-    /// VMI_DiamondShaped - Class is diamond shaped.
-    VMI_DiamondShaped = 0x2
-  };
-  
-  // Base class type info flags.
-  enum {
-    /// BCTI_Virtual - Base class is virtual.
-    BCTI_Virtual = 0x1,
-    
-    /// BCTI_Public - Base class is public.
-    BCTI_Public = 0x2
-  };
-  
-  /// BuildTypeInfo - Build the RTTI type info struct for the given type.
-  ///
-  /// \param Force - true to force the creation of this RTTI value
-  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
-};
-}
-
-llvm::GlobalVariable *
-ItaniumRTTIBuilder::GetAddrOfTypeName(QualType Ty,
-                               llvm::GlobalVariable::LinkageTypes Linkage) {
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  // We know that the mangled name of the type starts at index 4 of the
-  // mangled name of the typename, so we can just index into it in order to
-  // get the mangled name of the type.
-  llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
-                                                            Name.substr(4));
-
-  llvm::GlobalVariable *GV = 
-    CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);
-
-  GV->setInitializer(Init);
-
-  return GV;
-}
-
-llvm::Constant *
-ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
-  // Mangle the RTTI name.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  // Look for an existing global.
-  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
-  
-  if (!GV) {
-    // Create a new global variable.
-    GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
-                                  /*Constant=*/true,
-                                  llvm::GlobalValue::ExternalLinkage, nullptr,
-                                  Name);
-  }
-  
-  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
-}
-
-/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
-/// info for that type is defined in the standard library.
-static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
-  // Itanium C++ ABI 2.9.2:
-  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
-  //   the run-time support library. Specifically, the run-time support
-  //   library should contain type_info objects for the types X, X* and 
-  //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
-  //   unsigned char, signed char, short, unsigned short, int, unsigned int,
-  //   long, unsigned long, long long, unsigned long long, float, double,
-  //   long double, char16_t, char32_t, and the IEEE 754r decimal and 
-  //   half-precision floating point types.
-  switch (Ty->getKind()) {
-    case BuiltinType::Void:
-    case BuiltinType::NullPtr:
-    case BuiltinType::Bool:
-    case BuiltinType::WChar_S:
-    case BuiltinType::WChar_U:
-    case BuiltinType::Char_U:
-    case BuiltinType::Char_S:
-    case BuiltinType::UChar:
-    case BuiltinType::SChar:
-    case BuiltinType::Short:
-    case BuiltinType::UShort:
-    case BuiltinType::Int:
-    case BuiltinType::UInt:
-    case BuiltinType::Long:
-    case BuiltinType::ULong:
-    case BuiltinType::LongLong:
-    case BuiltinType::ULongLong:
-    case BuiltinType::Half:
-    case BuiltinType::Float:
-    case BuiltinType::Double:
-    case BuiltinType::LongDouble:
-    case BuiltinType::Char16:
-    case BuiltinType::Char32:
-    case BuiltinType::Int128:
-    case BuiltinType::UInt128:
-    case BuiltinType::OCLImage1d:
-    case BuiltinType::OCLImage1dArray:
-    case BuiltinType::OCLImage1dBuffer:
-    case BuiltinType::OCLImage2d:
-    case BuiltinType::OCLImage2dArray:
-    case BuiltinType::OCLImage3d:
-    case BuiltinType::OCLSampler:
-    case BuiltinType::OCLEvent:
-      return true;
-      
-    case BuiltinType::Dependent:
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) \
-    case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-      llvm_unreachable("asking for RRTI for a placeholder type!");
-      
-    case BuiltinType::ObjCId:
-    case BuiltinType::ObjCClass:
-    case BuiltinType::ObjCSel:
-      llvm_unreachable("FIXME: Objective-C types are unsupported!");
-  }
-
-  llvm_unreachable("Invalid BuiltinType Kind!");
-}
-
-static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
-  QualType PointeeTy = PointerTy->getPointeeType();
-  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
-  if (!BuiltinTy)
-    return false;
-    
-  // Check the qualifiers.
-  Qualifiers Quals = PointeeTy.getQualifiers();
-  Quals.removeConst();
-    
-  if (!Quals.empty())
-    return false;
-    
-  return TypeInfoIsInStandardLibrary(BuiltinTy);
-}
-
-/// IsStandardLibraryRTTIDescriptor - Returns whether the type
-/// information for the given type exists in the standard library.
-static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
-  // Type info for builtin types is defined in the standard library.
-  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
-    return TypeInfoIsInStandardLibrary(BuiltinTy);
-  
-  // Type info for some pointer types to builtin types is defined in the
-  // standard library.
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
-    return TypeInfoIsInStandardLibrary(PointerTy);
-
-  return false;
-}
-
-/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
-/// the given type exists somewhere else, and that we should not emit the type
-/// information in this translation unit.  Assumes that it is not a
-/// standard-library type.
-static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
-                                            QualType Ty) {
-  ASTContext &Context = CGM.getContext();
-
-  // If RTTI is disabled, assume it might be disabled in the
-  // translation unit that defines any potential key function, too.
-  if (!Context.getLangOpts().RTTI) return false;
-
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
-    if (!RD->hasDefinition())
-      return false;
-
-    if (!RD->isDynamicClass())
-      return false;
-
-    // FIXME: this may need to be reconsidered if the key function
-    // changes.
-    return CGM.getVTables().isVTableExternal(RD);
-  }
-  
-  return false;
-}
-
-/// IsIncompleteClassType - Returns whether the given record type is incomplete.
-static bool IsIncompleteClassType(const RecordType *RecordTy) {
-  return !RecordTy->getDecl()->isCompleteDefinition();
-}  
-
-/// ContainsIncompleteClassType - Returns whether the given type contains an
-/// incomplete class type. This is true if
-///
-///   * The given type is an incomplete class type.
-///   * The given type is a pointer type whose pointee type contains an 
-///     incomplete class type.
-///   * The given type is a member pointer type whose class is an incomplete
-///     class type.
-///   * The given type is a member pointer type whoise pointee type contains an
-///     incomplete class type.
-/// is an indirect or direct pointer to an incomplete class type.
-static bool ContainsIncompleteClassType(QualType Ty) {
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    if (IsIncompleteClassType(RecordTy))
-      return true;
-  }
-  
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
-    return ContainsIncompleteClassType(PointerTy->getPointeeType());
-  
-  if (const MemberPointerType *MemberPointerTy = 
-      dyn_cast<MemberPointerType>(Ty)) {
-    // Check if the class type is incomplete.
-    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
-    if (IsIncompleteClassType(ClassType))
-      return true;
-    
-    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
-  }
-  
-  return false;
-}
-
-/// getTypeInfoLinkage - Return the linkage that the type info and type info
-/// name constants should have for the given type.
-llvm::GlobalVariable::LinkageTypes 
-CodeGenModule::getTypeInfoLinkage(QualType Ty) {
-  // Itanium C++ ABI 2.9.5p7:
-  //   In addition, it and all of the intermediate abi::__pointer_type_info 
-  //   structs in the chain down to the abi::__class_type_info for the
-  //   incomplete class type must be prevented from resolving to the 
-  //   corresponding type_info structs for the complete class type, possibly
-  //   by making them local static objects. Finally, a dummy class RTTI is
-  //   generated for the incomplete type that will not resolve to the final 
-  //   complete class RTTI (because the latter need not exist), possibly by 
-  //   making it a local static object.
-  if (ContainsIncompleteClassType(Ty))
-    return llvm::GlobalValue::InternalLinkage;
-  
-  switch (Ty->getLinkage()) {
-  case NoLinkage:
-  case InternalLinkage:
-  case UniqueExternalLinkage:
-    return llvm::GlobalValue::InternalLinkage;
-
-  case VisibleNoLinkage:
-  case ExternalLinkage:
-    if (!getLangOpts().RTTI) {
-      // RTTI is not enabled, which means that this type info struct is going
-      // to be used for exception handling. Give it linkonce_odr linkage.
-      return llvm::GlobalValue::LinkOnceODRLinkage;
-    }
-
-    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
-      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
-      if (RD->hasAttr<WeakAttr>())
-        return llvm::GlobalValue::WeakODRLinkage;
-      if (RD->isDynamicClass())
-        return getVTableLinkage(RD);
-    }
-
-    return llvm::GlobalValue::LinkOnceODRLinkage;
-  }
-
-  llvm_unreachable("Invalid linkage!");
-}
-
-// CanUseSingleInheritance - Return whether the given record decl has a "single, 
-// public, non-virtual base at offset zero (i.e. the derived class is dynamic 
-// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
-static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
-  // Check the number of bases.
-  if (RD->getNumBases() != 1)
-    return false;
-  
-  // Get the base.
-  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
-  
-  // Check that the base is not virtual.
-  if (Base->isVirtual())
-    return false;
-  
-  // Check that the base is public.
-  if (Base->getAccessSpecifier() != AS_public)
-    return false;
-  
-  // Check that the class is dynamic iff the base is.
-  const CXXRecordDecl *BaseDecl = 
-    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-  if (!BaseDecl->isEmpty() && 
-      BaseDecl->isDynamicClass() != RD->isDynamicClass())
-    return false;
-  
-  return true;
-}
-
-void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
-  // abi::__class_type_info.
-  static const char * const ClassTypeInfo =
-    "_ZTVN10__cxxabiv117__class_type_infoE";
-  // abi::__si_class_type_info.
-  static const char * const SIClassTypeInfo =
-    "_ZTVN10__cxxabiv120__si_class_type_infoE";
-  // abi::__vmi_class_type_info.
-  static const char * const VMIClassTypeInfo =
-    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
-
-  const char *VTableName = nullptr;
-
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
-
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
-
-  case Type::Auto:
-    llvm_unreachable("Undeduced auto type shouldn't get here");
-
-  case Type::Builtin:
-  // GCC treats vector and complex types as fundamental types.
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::Atomic:
-  // FIXME: GCC treats block pointers as fundamental types?!
-  case Type::BlockPointer:
-    // abi::__fundamental_type_info.
-    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
-    break;
-
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // abi::__array_type_info.
-    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
-    break;
-
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // abi::__function_type_info.
-    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
-    break;
-
-  case Type::Enum:
-    // abi::__enum_type_info.
-    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
-    break;
-
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
-    
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      VTableName = ClassTypeInfo;
-    } else if (CanUseSingleInheritance(RD)) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = VMIClassTypeInfo;
-    }
-    
-    break;
-  }
-
-  case Type::ObjCObject:
-    // Ignore protocol qualifiers.
-    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
-
-    // Handle id and Class.
-    if (isa<BuiltinType>(Ty)) {
-      VTableName = ClassTypeInfo;
-      break;
-    }
-
-    assert(isa<ObjCInterfaceType>(Ty));
-    // Fall through.
-
-  case Type::ObjCInterface:
-    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = ClassTypeInfo;
-    }
-    break;
-
-  case Type::ObjCObjectPointer:
-  case Type::Pointer:
-    // abi::__pointer_type_info.
-    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
-    break;
-
-  case Type::MemberPointer:
-    // abi::__pointer_to_member_type_info.
-    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
-    break;
-  }
-
-  llvm::Constant *VTable = 
-    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
-    
-  llvm::Type *PtrDiffTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
-
-  // The vtable address point is 2.
-  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
-  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
-  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
-
-  Fields.push_back(VTable);
-}
-
-llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
-  // We want to operate on the canonical type.
-  Ty = CGM.getContext().getCanonicalType(Ty);
-
-  // Check if we've already emitted an RTTI descriptor for this type.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
-  if (OldGV && !OldGV->isDeclaration()) {
-    assert(!OldGV->hasAvailableExternallyLinkage() &&
-           "available_externally typeinfos not yet implemented");
-
-    return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
-  }
-
-  // Check if there is already an external RTTI descriptor for this type.
-  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
-  if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
-    return GetAddrOfExternalRTTIDescriptor(Ty);
-
-  // Emit the standard library with external linkage.
-  llvm::GlobalVariable::LinkageTypes Linkage;
-  if (IsStdLib)
-    Linkage = llvm::GlobalValue::ExternalLinkage;
-  else
-    Linkage = CGM.getTypeInfoLinkage(Ty);
-
-  // Add the vtable pointer.
-  BuildVTablePointer(cast<Type>(Ty));
-  
-  // And the name.
-  llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
-  llvm::Constant *TypeNameField;
-
-  // If we're supposed to demote the visibility, be sure to set a flag
-  // to use a string comparison for type_info comparisons.
-  CGCXXABI::RTTIUniquenessKind RTTIUniqueness =
-      CGM.getCXXABI().classifyRTTIUniqueness(Ty, Linkage);
-  if (RTTIUniqueness != CGCXXABI::RUK_Unique) {
-    // The flag is the sign bit, which on ARM64 is defined to be clear
-    // for global pointers.  This is very ARM64-specific.
-    TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
-    llvm::Constant *flag =
-        llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);
-    TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
-    TypeNameField =
-        llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy);
-  } else {
-    TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
-  }
-  Fields.push_back(TypeNameField);
-
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
-
-  // GCC treats vector types as fundamental types.
-  case Type::Builtin:
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::BlockPointer:
-    // Itanium C++ ABI 2.9.5p4:
-    // abi::__fundamental_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
-
-  case Type::Auto:
-    llvm_unreachable("Undeduced auto type shouldn't get here");
-
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__array_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__function_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::Enum:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__enum_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      // We don't need to emit any fields.
-      break;
-    }
-    
-    if (CanUseSingleInheritance(RD))
-      BuildSIClassTypeInfo(RD);
-    else 
-      BuildVMIClassTypeInfo(RD);
-
-    break;
-  }
-
-  case Type::ObjCObject:
-  case Type::ObjCInterface:
-    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
-    break;
-
-  case Type::ObjCObjectPointer:
-    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
-    break; 
-      
-  case Type::Pointer:
-    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
-    break;
-
-  case Type::MemberPointer:
-    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
-    break;
-
-  case Type::Atomic:
-    // No fields, at least for the moment.
-    break;
-  }
-
-  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
-
-  llvm::GlobalVariable *GV = 
-    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 
-                             /*Constant=*/true, Linkage, Init, Name);
-  
-  // If there's already an old global variable, replace it with the new one.
-  if (OldGV) {
-    GV->takeName(OldGV);
-    llvm::Constant *NewPtr = 
-      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
-    OldGV->replaceAllUsesWith(NewPtr);
-    OldGV->eraseFromParent();
-  }
-
-  // The Itanium ABI specifies that type_info objects must be globally
-  // unique, with one exception: if the type is an incomplete class
-  // type or a (possibly indirect) pointer to one.  That exception
-  // affects the general case of comparing type_info objects produced
-  // by the typeid operator, which is why the comparison operators on
-  // std::type_info generally use the type_info name pointers instead
-  // of the object addresses.  However, the language's built-in uses
-  // of RTTI generally require class types to be complete, even when
-  // manipulating pointers to those class types.  This allows the
-  // implementation of dynamic_cast to rely on address equality tests,
-  // which is much faster.
-
-  // All of this is to say that it's important that both the type_info
-  // object and the type_info name be uniqued when weakly emitted.
-
-  // Give the type_info object and name the formal visibility of the
-  // type itself.
-  llvm::GlobalValue::VisibilityTypes llvmVisibility;
-  if (llvm::GlobalValue::isLocalLinkage(Linkage))
-    // If the linkage is local, only default visibility makes sense.
-    llvmVisibility = llvm::GlobalValue::DefaultVisibility;
-  else if (RTTIUniqueness == CGCXXABI::RUK_NonUniqueHidden)
-    llvmVisibility = llvm::GlobalValue::HiddenVisibility;
-  else
-    llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
-  TypeName->setVisibility(llvmVisibility);
-  GV->setVisibility(llvmVisibility);
-
-  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
-}
-
-/// ComputeQualifierFlags - Compute the pointer type info flags from the
-/// given qualifier.
-static unsigned ComputeQualifierFlags(Qualifiers Quals) {
-  unsigned Flags = 0;
-
-  if (Quals.hasConst())
-    Flags |= ItaniumRTTIBuilder::PTI_Const;
-  if (Quals.hasVolatile())
-    Flags |= ItaniumRTTIBuilder::PTI_Volatile;
-  if (Quals.hasRestrict())
-    Flags |= ItaniumRTTIBuilder::PTI_Restrict;
-
-  return Flags;
-}
-
-/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
-/// for the given Objective-C object type.
-void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
-  // Drop qualifiers.
-  const Type *T = OT->getBaseType().getTypePtr();
-  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
-
-  // The builtin types are abi::__class_type_infos and don't require
-  // extra fields.
-  if (isa<BuiltinType>(T)) return;
-
-  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
-  ObjCInterfaceDecl *Super = Class->getSuperClass();
-
-  // Root classes are also __class_type_info.
-  if (!Super) return;
-
-  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
-
-  // Everything else is single inheritance.
-  llvm::Constant *BaseTypeInfo = ItaniumRTTIBuilder(CGM).BuildTypeInfo(SuperTy);
-  Fields.push_back(BaseTypeInfo);
-}
-
-/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
-/// inheritance, according to the Itanium C++ ABI, 2.95p6b.
-void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
-  // Itanium C++ ABI 2.9.5p6b:
-  // It adds to abi::__class_type_info a single member pointing to the 
-  // type_info structure for the base type,
-  llvm::Constant *BaseTypeInfo = 
-    ItaniumRTTIBuilder(CGM).BuildTypeInfo(RD->bases_begin()->getType());
-  Fields.push_back(BaseTypeInfo);
-}
-
-namespace {
-  /// SeenBases - Contains virtual and non-virtual bases seen when traversing
-  /// a class hierarchy.
-  struct SeenBases {
-    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
-    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
-  };
-}
-
-/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
-/// abi::__vmi_class_type_info.
-///
-static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 
-                                             SeenBases &Bases) {
-  
-  unsigned Flags = 0;
-  
-  const CXXRecordDecl *BaseDecl = 
-    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-  
-  if (Base->isVirtual()) {
-    // Mark the virtual base as seen.
-    if (!Bases.VirtualBases.insert(BaseDecl)) {
-      // If this virtual base has been seen before, then the class is diamond
-      // shaped.
-      Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
-    } else {
-      if (Bases.NonVirtualBases.count(BaseDecl))
-        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
-    }
-  } else {
-    // Mark the non-virtual base as seen.
-    if (!Bases.NonVirtualBases.insert(BaseDecl)) {
-      // If this non-virtual base has been seen before, then the class has non-
-      // diamond shaped repeated inheritance.
-      Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
-    } else {
-      if (Bases.VirtualBases.count(BaseDecl))
-        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
-    }
-  }
-
-  // Walk all bases.
-  for (const auto &I : BaseDecl->bases()) 
-    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
-  
-  return Flags;
-}
-
-static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
-  unsigned Flags = 0;
-  SeenBases Bases;
-  
-  // Walk all bases.
-  for (const auto &I : RD->bases()) 
-    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
-  
-  return Flags;
-}
-
-/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
-/// classes with bases that do not satisfy the abi::__si_class_type_info 
-/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
-void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __flags is a word with flags describing details about the class 
-  //   structure, which may be referenced by using the __flags_masks 
-  //   enumeration. These flags refer to both direct and indirect bases. 
-  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __base_count is a word with the number of direct proper base class 
-  //   descriptions that follow.
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
-  
-  if (!RD->getNumBases())
-    return;
-  
-  llvm::Type *LongLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().LongTy);
-
-  // Now add the base class descriptions.
-  
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __base_info[] is an array of base class descriptions -- one for every 
-  //   direct proper base. Each description is of the type:
-  //
-  //   struct abi::__base_class_type_info {
-  //   public:
-  //     const __class_type_info *__base_type;
-  //     long __offset_flags;
-  //
-  //     enum __offset_flags_masks {
-  //       __virtual_mask = 0x1,
-  //       __public_mask = 0x2,
-  //       __offset_shift = 8
-  //     };
-  //   };
-  for (const auto &Base : RD->bases()) {
-    // The __base_type member points to the RTTI for the base type.
-    Fields.push_back(ItaniumRTTIBuilder(CGM).BuildTypeInfo(Base.getType()));
-
-    const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
-
-    int64_t OffsetFlags = 0;
-    
-    // All but the lower 8 bits of __offset_flags are a signed offset. 
-    // For a non-virtual base, this is the offset in the object of the base
-    // subobject. For a virtual base, this is the offset in the virtual table of
-    // the virtual base offset for the virtual base referenced (negative).
-    CharUnits Offset;
-    if (Base.isVirtual())
-      Offset = 
-        CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
-    else {
-      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
-      Offset = Layout.getBaseClassOffset(BaseDecl);
-    };
-    
-    OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
-    
-    // The low-order byte of __offset_flags contains flags, as given by the 
-    // masks from the enumeration __offset_flags_masks.
-    if (Base.isVirtual())
-      OffsetFlags |= BCTI_Virtual;
-    if (Base.getAccessSpecifier() == AS_public)
-      OffsetFlags |= BCTI_Public;
-
-    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
-  }
-}
-
-/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
-/// used for pointer types.
-void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
-  Qualifiers Quals;
-  QualType UnqualifiedPointeeTy = 
-    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __flags is a flag word describing the cv-qualification and other 
-  //   attributes of the type pointed to
-  unsigned Flags = ComputeQualifierFlags(Quals);
-
-  // Itanium C++ ABI 2.9.5p7:
-  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
-  //   incomplete class type, the incomplete target type flag is set. 
-  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
-    Flags |= PTI_Incomplete;
-
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //  __pointee is a pointer to the std::type_info derivation for the 
-  //  unqualified type being pointed to.
-  llvm::Constant *PointeeTypeInfo = 
-    ItaniumRTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
-  Fields.push_back(PointeeTypeInfo);
-}
-
-/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
-/// struct, used for member pointer types.
-void
-ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
-  QualType PointeeTy = Ty->getPointeeType();
-  
-  Qualifiers Quals;
-  QualType UnqualifiedPointeeTy = 
-    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __flags is a flag word describing the cv-qualification and other 
-  //   attributes of the type pointed to.
-  unsigned Flags = ComputeQualifierFlags(Quals);
-
-  const RecordType *ClassType = cast<RecordType>(Ty->getClass());
-
-  // Itanium C++ ABI 2.9.5p7:
-  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
-  //   incomplete class type, the incomplete target type flag is set. 
-  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
-    Flags |= PTI_Incomplete;
-
-  if (IsIncompleteClassType(ClassType))
-    Flags |= PTI_ContainingClassIncomplete;
-  
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __pointee is a pointer to the std::type_info derivation for the 
-  //   unqualified type being pointed to.
-  llvm::Constant *PointeeTypeInfo = 
-    ItaniumRTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
-  Fields.push_back(PointeeTypeInfo);
-
-  // Itanium C++ ABI 2.9.5p9:
-  //   __context is a pointer to an abi::__class_type_info corresponding to the
-  //   class type containing the member pointed to 
-  //   (e.g., the "A" in "int A::*").
-  Fields.push_back(
-      ItaniumRTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
-}
-
-llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
-                                                       bool ForEH) {
-  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
-  // FIXME: should we even be calling this method if RTTI is disabled
-  // and it's not for EH?
-  if (!ForEH && !getLangOpts().RTTI)
-    return llvm::Constant::getNullValue(Int8PtrTy);
-  
-  if (ForEH && Ty->isObjCObjectPointerType() &&
-      LangOpts.ObjCRuntime.isGNUFamily())
-    return ObjCRuntime->GetEHType(Ty);
-
-  if (getTarget().getCXXABI().isMicrosoft())
-    return getMSTypeDescriptor(Ty);
-  return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
-}
-
-void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
-  QualType PointerType = Context.getPointerType(Type);
-  QualType PointerTypeConst = Context.getPointerType(Type.withConst());
-  ItaniumRTTIBuilder(*this).BuildTypeInfo(Type, true);
-  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, true);
-  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
-}
-
-void CodeGenModule::EmitFundamentalRTTIDescriptors() {
-  QualType FundamentalTypes[] = { Context.VoidTy, Context.NullPtrTy,
-                                  Context.BoolTy, Context.WCharTy,
-                                  Context.CharTy, Context.UnsignedCharTy,
-                                  Context.SignedCharTy, Context.ShortTy, 
-                                  Context.UnsignedShortTy, Context.IntTy,
-                                  Context.UnsignedIntTy, Context.LongTy, 
-                                  Context.UnsignedLongTy, Context.LongLongTy, 
-                                  Context.UnsignedLongLongTy,
-                                  Context.HalfTy, Context.FloatTy,
-                                  Context.DoubleTy, Context.LongDoubleTy,
-                                  Context.Char16Ty, Context.Char32Ty };
-  for (unsigned i = 0; i < llvm::array_lengthof(FundamentalTypes); ++i)
-    EmitFundamentalRTTIDescriptor(FundamentalTypes[i]);
-}
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 573973a..cd86eeb 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/CallSite.h"
@@ -172,12 +173,33 @@
   case Stmt::SEHTryStmtClass:
     EmitSEHTryStmt(cast<SEHTryStmt>(*S));
     break;
+  case Stmt::SEHLeaveStmtClass:
+    EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S));
+    break;
   case Stmt::OMPParallelDirectiveClass:
     EmitOMPParallelDirective(cast<OMPParallelDirective>(*S));
     break;
   case Stmt::OMPSimdDirectiveClass:
     EmitOMPSimdDirective(cast<OMPSimdDirective>(*S));
     break;
+  case Stmt::OMPForDirectiveClass:
+    EmitOMPForDirective(cast<OMPForDirective>(*S));
+    break;
+  case Stmt::OMPSectionsDirectiveClass:
+    EmitOMPSectionsDirective(cast<OMPSectionsDirective>(*S));
+    break;
+  case Stmt::OMPSectionDirectiveClass:
+    EmitOMPSectionDirective(cast<OMPSectionDirective>(*S));
+    break;
+  case Stmt::OMPSingleDirectiveClass:
+    EmitOMPSingleDirective(cast<OMPSingleDirective>(*S));
+    break;
+  case Stmt::OMPParallelForDirectiveClass:
+    EmitOMPParallelForDirective(cast<OMPParallelForDirective>(*S));
+    break;
+  case Stmt::OMPParallelSectionsDirectiveClass:
+    EmitOMPParallelSectionsDirective(cast<OMPParallelSectionsDirective>(*S));
+    break;
   }
 }
 
@@ -398,7 +420,23 @@
 }
 
 void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {
-  EmitStmt(S.getSubStmt());
+  const Stmt *SubStmt = S.getSubStmt();
+  switch (SubStmt->getStmtClass()) {
+  case Stmt::DoStmtClass:
+    EmitDoStmt(cast<DoStmt>(*SubStmt), S.getAttrs());
+    break;
+  case Stmt::ForStmtClass:
+    EmitForStmt(cast<ForStmt>(*SubStmt), S.getAttrs());
+    break;
+  case Stmt::WhileStmtClass:
+    EmitWhileStmt(cast<WhileStmt>(*SubStmt), S.getAttrs());
+    break;
+  case Stmt::CXXForRangeStmtClass:
+    EmitCXXForRangeStmt(cast<CXXForRangeStmt>(*SubStmt), S.getAttrs());
+    break;
+  default:
+    EmitStmt(SubStmt);
+  }
 }
 
 void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
@@ -436,7 +474,7 @@
 void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
   // C99 6.8.4.1: The first substatement is executed if the expression compares
   // unequal to 0.  The condition must be a scalar type.
-  LexicalScope ConditionScope(*this, S.getSourceRange());
+  LexicalScope ConditionScope(*this, S.getCond()->getSourceRange());
   RegionCounter Cnt = getPGORegionCounter(&S);
 
   if (S.getConditionVariable())
@@ -504,7 +542,92 @@
   EmitBlock(ContBlock, true);
 }
 
-void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
+void CodeGenFunction::EmitCondBrHints(llvm::LLVMContext &Context,
+                                      llvm::BranchInst *CondBr,
+                                      const ArrayRef<const Attr *> &Attrs) {
+  // Return if there are no hints.
+  if (Attrs.empty())
+    return;
+
+  // Add vectorize and unroll hints to the metadata on the conditional branch.
+  SmallVector<llvm::Value *, 2> Metadata(1);
+  for (const auto *Attr : Attrs) {
+    const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
+
+    // Skip non loop hint attributes
+    if (!LH)
+      continue;
+
+    LoopHintAttr::OptionType Option = LH->getOption();
+    int ValueInt = LH->getValue();
+
+    const char *MetadataName;
+    switch (Option) {
+    case LoopHintAttr::Vectorize:
+    case LoopHintAttr::VectorizeWidth:
+      MetadataName = "llvm.loop.vectorize.width";
+      break;
+    case LoopHintAttr::Interleave:
+    case LoopHintAttr::InterleaveCount:
+      MetadataName = "llvm.loop.vectorize.unroll";
+      break;
+    case LoopHintAttr::Unroll:
+      MetadataName = "llvm.loop.unroll.enable";
+      break;
+    case LoopHintAttr::UnrollCount:
+      MetadataName = "llvm.loop.unroll.count";
+      break;
+    }
+
+    llvm::Value *Value;
+    llvm::MDString *Name;
+    switch (Option) {
+    case LoopHintAttr::Vectorize:
+    case LoopHintAttr::Interleave:
+      if (ValueInt == 1) {
+        // FIXME: In the future I will modifiy the behavior of the metadata
+        // so we can enable/disable vectorization and interleaving separately.
+        Name = llvm::MDString::get(Context, "llvm.loop.vectorize.enable");
+        Value = Builder.getTrue();
+        break;
+      }
+      // Vectorization/interleaving is disabled, set width/count to 1.
+      ValueInt = 1;
+      // Fallthrough.
+    case LoopHintAttr::VectorizeWidth:
+    case LoopHintAttr::InterleaveCount:
+      Name = llvm::MDString::get(Context, MetadataName);
+      Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
+      break;
+    case LoopHintAttr::Unroll:
+      Name = llvm::MDString::get(Context, MetadataName);
+      Value = (ValueInt == 0) ? Builder.getFalse() : Builder.getTrue();
+      break;
+    case LoopHintAttr::UnrollCount:
+      Name = llvm::MDString::get(Context, MetadataName);
+      Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
+      break;
+    }
+
+    SmallVector<llvm::Value *, 2> OpValues;
+    OpValues.push_back(Name);
+    OpValues.push_back(Value);
+
+    // Set or overwrite metadata indicated by Name.
+    Metadata.push_back(llvm::MDNode::get(Context, OpValues));
+  }
+
+  if (!Metadata.empty()) {
+    // Add llvm.loop MDNode to CondBr.
+    llvm::MDNode *LoopID = llvm::MDNode::get(Context, Metadata);
+    LoopID->replaceOperandWith(0, LoopID); // First op points to itself.
+
+    CondBr->setMetadata("llvm.loop", LoopID);
+  }
+}
+
+void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
+                                    const ArrayRef<const Attr *> &WhileAttrs) {
   RegionCounter Cnt = getPGORegionCounter(&S);
 
   // Emit the header for the loop, which will also become
@@ -551,13 +674,17 @@
     llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
     if (ConditionScope.requiresCleanups())
       ExitBlock = createBasicBlock("while.exit");
-    Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
-                         PGO.createLoopWeights(S.getCond(), Cnt));
+    llvm::BranchInst *CondBr =
+        Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
+                             PGO.createLoopWeights(S.getCond(), Cnt));
 
     if (ExitBlock != LoopExit.getBlock()) {
       EmitBlock(ExitBlock);
       EmitBranchThroughCleanup(LoopExit);
     }
+
+    // Attach metadata to loop body conditional branch.
+    EmitCondBrHints(LoopBody->getContext(), CondBr, WhileAttrs);
   }
 
   // Emit the loop body.  We have to emit this in a cleanup scope
@@ -588,7 +715,8 @@
     SimplifyForwardingBlocks(LoopHeader.getBlock());
 }
 
-void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
+void CodeGenFunction::EmitDoStmt(const DoStmt &S,
+                                 const ArrayRef<const Attr *> &DoAttrs) {
   JumpDest LoopExit = getJumpDestInCurrentScope("do.end");
   JumpDest LoopCond = getJumpDestInCurrentScope("do.cond");
 
@@ -628,9 +756,14 @@
       EmitBoolCondBranch = false;
 
   // As long as the condition is true, iterate the loop.
-  if (EmitBoolCondBranch)
-    Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock(),
-                         PGO.createLoopWeights(S.getCond(), Cnt));
+  if (EmitBoolCondBranch) {
+    llvm::BranchInst *CondBr =
+        Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock(),
+                             PGO.createLoopWeights(S.getCond(), Cnt));
+
+    // Attach metadata to loop body conditional branch.
+    EmitCondBrHints(LoopBody->getContext(), CondBr, DoAttrs);
+  }
 
   LoopStack.pop();
 
@@ -643,7 +776,8 @@
     SimplifyForwardingBlocks(LoopCond.getBlock());
 }
 
-void CodeGenFunction::EmitForStmt(const ForStmt &S) {
+void CodeGenFunction::EmitForStmt(const ForStmt &S,
+                                  const ArrayRef<const Attr *> &ForAttrs) {
   JumpDest LoopExit = getJumpDestInCurrentScope("for.end");
 
   RunCleanupsScope ForScope(*this);
@@ -699,8 +833,12 @@
     // C99 6.8.5p2/p4: The first substatement is executed if the expression
     // compares unequal to 0.  The condition must be a scalar type.
     llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-    Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock,
-                         PGO.createLoopWeights(S.getCond(), Cnt));
+    llvm::BranchInst *CondBr =
+        Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock,
+                             PGO.createLoopWeights(S.getCond(), Cnt));
+
+    // Attach metadata to loop body conditional branch.
+    EmitCondBrHints(ForBody->getContext(), CondBr, ForAttrs);
 
     if (ExitBlock != LoopExit.getBlock()) {
       EmitBlock(ExitBlock);
@@ -743,7 +881,9 @@
   EmitBlock(LoopExit.getBlock(), true);
 }
 
-void CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S) {
+void
+CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
+                                     const ArrayRef<const Attr *> &ForAttrs) {
   JumpDest LoopExit = getJumpDestInCurrentScope("for.end");
 
   RunCleanupsScope ForScope(*this);
@@ -778,8 +918,11 @@
   // The body is executed if the expression, contextually converted
   // to bool, is true.
   llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-  Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock,
-                       PGO.createLoopWeights(S.getCond(), Cnt));
+  llvm::BranchInst *CondBr = Builder.CreateCondBr(
+      BoolCondVal, ForBody, ExitBlock, PGO.createLoopWeights(S.getCond(), Cnt));
+
+  // Attach metadata to loop body conditional branch.
+  EmitCondBrHints(ForBody->getContext(), CondBr, ForAttrs);
 
   if (ExitBlock != LoopExit.getBlock()) {
     EmitBlock(ExitBlock);
@@ -1920,20 +2063,32 @@
   return SlotLV;
 }
 
+static void InitVLACaptures(CodeGenFunction &CGF, const CapturedStmt &S) {
+  for (auto &C : S.captures()) {
+    if (C.capturesVariable()) {
+      QualType QTy;
+      auto VD = C.getCapturedVar();
+      if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
+        QTy = PVD->getOriginalType();
+      else
+        QTy = VD->getType();
+      if (QTy->isVariablyModifiedType()) {
+        CGF.EmitVariablyModifiedType(QTy);
+      }
+    }
+  }
+}
+
 /// Generate an outlined function for the body of a CapturedStmt, store any
 /// captured variables into the captured struct, and call the outlined function.
 llvm::Function *
 CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) {
-  const CapturedDecl *CD = S.getCapturedDecl();
-  const RecordDecl *RD = S.getCapturedRecordDecl();
-  assert(CD->hasBody() && "missing CapturedDecl body");
-
   LValue CapStruct = InitCapturedStruct(*this, S);
 
   // Emit the CapturedDecl
   CodeGenFunction CGF(CGM, true);
   CGF.CapturedStmtInfo = new CGCapturedStmtInfo(S, K);
-  llvm::Function *F = CGF.GenerateCapturedStmtFunction(CD, RD, S.getLocStart());
+  llvm::Function *F = CGF.GenerateCapturedStmtFunction(S);
   delete CGF.CapturedStmtInfo;
 
   // Emit call to the helper function.
@@ -1950,11 +2105,13 @@
 
 /// Creates the outlined function for a CapturedStmt.
 llvm::Function *
-CodeGenFunction::GenerateCapturedStmtFunction(const CapturedDecl *CD,
-                                              const RecordDecl *RD,
-                                              SourceLocation Loc) {
+CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) {
   assert(CapturedStmtInfo &&
     "CapturedStmtInfo should be set when generating the captured function");
+  const CapturedDecl *CD = S.getCapturedDecl();
+  const RecordDecl *RD = S.getCapturedRecordDecl();
+  SourceLocation Loc = S.getLocStart();
+  assert(CD->hasBody() && "missing CapturedDecl body");
 
   // Build the argument list.
   ASTContext &Ctx = CGM.getContext();
@@ -1977,12 +2134,14 @@
   StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args,
                 CD->getLocation(),
                 CD->getBody()->getLocStart());
-
   // Set the context parameter in CapturedStmtInfo.
   llvm::Value *DeclPtr = LocalDeclMap[CD->getContextParam()];
   assert(DeclPtr && "missing context parameter for CapturedStmt");
   CapturedStmtInfo->setContextValue(Builder.CreateLoad(DeclPtr));
 
+  // Initialize variable-length arrays.
+  InitVLACaptures(*this, S);
+
   // If 'this' is captured, load it into CXXThisValue.
   if (CapturedStmtInfo->isCXXThisExprCaptured()) {
     FieldDecl *FD = CapturedStmtInfo->getThisFieldDecl();
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 17d8dd1..e253efc 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -32,19 +32,17 @@
     CodeGenFunction CGF(CGM, true);
     CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind());
     CGF.CapturedStmtInfo = &CGInfo;
-    OutlinedFn = CGF.GenerateCapturedStmtFunction(
-        CS->getCapturedDecl(), CS->getCapturedRecordDecl(), CS->getLocStart());
+    OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS);
   }
 
   // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
   llvm::Value *Args[] = {
-    CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
-    Builder.getInt32(1), // Number of arguments after 'microtask' argument
-                         // (there is only one additional argument - 'context')
-    Builder.CreateBitCast(OutlinedFn,
-                          CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
-    EmitCastToVoidPtr(CapturedStruct)
-  };
+      CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
+      Builder.getInt32(1), // Number of arguments after 'microtask' argument
+      // (there is only one additional argument - 'context')
+      Builder.CreateBitCast(OutlinedFn,
+                            CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
+      EmitCastToVoidPtr(CapturedStruct)};
   llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction(
       CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
   EmitRuntimeCall(RTLFn, Args);
@@ -76,3 +74,29 @@
   EmitStmt(Body);
 }
 
+void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
+  llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
+  llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
+  llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
+  llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
+}
+
+void
+CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
+  llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPParallelSectionsDirective(
+    const OMPParallelSectionsDirective &) {
+  llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
+}
+
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index d10db5a..0df2c43 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -382,12 +382,14 @@
     // FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly.
     if (!UseAvailableExternallyLinkage) {
       CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk);
-      CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);
+      CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
+                                      !Thunk.Return.isEmpty());
     }
   } else {
     // Normal thunk body generation.
     CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk);
-    CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);
+    CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
+                                    !Thunk.Return.isEmpty());
   }
 }
 
@@ -429,12 +431,10 @@
     emitThunk(GD, (*ThunkInfoVector)[I], /*ForVTable=*/false);
 }
 
-llvm::Constant *
-CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
-                                        const VTableComponent *Components, 
-                                        unsigned NumComponents,
-                                const VTableLayout::VTableThunkTy *VTableThunks,
-                                        unsigned NumVTableThunks) {
+llvm::Constant *CodeGenVTables::CreateVTableInitializer(
+    const CXXRecordDecl *RD, const VTableComponent *Components,
+    unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
+    unsigned NumVTableThunks, llvm::Constant *RTTI) {
   SmallVector<llvm::Constant *, 64> Inits;
 
   llvm::Type *Int8PtrTy = CGM.Int8PtrTy;
@@ -442,9 +442,6 @@
   llvm::Type *PtrDiffTy = 
     CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
 
-  QualType ClassType = CGM.getContext().getTagDeclType(RD);
-  llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(ClassType);
-  
   unsigned NextVTableThunkIndex = 0;
 
   llvm::Constant *PureVirtualFn = nullptr, *DeletedVirtualFn = nullptr;
@@ -592,13 +589,14 @@
   // V-tables are always unnamed_addr.
   VTable->setUnnamedAddr(true);
 
+  llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
+      CGM.getContext().getTagDeclType(Base.getBase()));
+
   // Create and set the initializer.
-  llvm::Constant *Init = 
-    CreateVTableInitializer(Base.getBase(), 
-                            VTLayout->vtable_component_begin(), 
-                            VTLayout->getNumVTableComponents(),
-                            VTLayout->vtable_thunk_begin(),
-                            VTLayout->getNumVTableThunks());
+  llvm::Constant *Init = CreateVTableInitializer(
+      Base.getBase(), VTLayout->vtable_component_begin(),
+      VTLayout->getNumVTableComponents(), VTLayout->vtable_thunk_begin(),
+      VTLayout->getNumVTableThunks(), RTTI);
   VTable->setInitializer(Init);
   
   return VTable;
@@ -651,18 +649,31 @@
   // internal linkage.
   if (Context.getLangOpts().AppleKext)
     return llvm::Function::InternalLinkage;
-  
+
+  llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
+      llvm::GlobalValue::LinkOnceODRLinkage;
+  llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
+      llvm::GlobalValue::WeakODRLinkage;
+  if (RD->hasAttr<DLLExportAttr>()) {
+    // Cannot discard exported vtables.
+    DiscardableODRLinkage = NonDiscardableODRLinkage;
+  } else if (RD->hasAttr<DLLImportAttr>()) {
+    // Imported vtables are available externally.
+    DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
+    NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
+  }
+
   switch (RD->getTemplateSpecializationKind()) {
   case TSK_Undeclared:
   case TSK_ExplicitSpecialization:
   case TSK_ImplicitInstantiation:
-    return llvm::GlobalVariable::LinkOnceODRLinkage;
+    return DiscardableODRLinkage;
 
   case TSK_ExplicitInstantiationDeclaration:
     llvm_unreachable("Should not have been asked to emit this");
 
   case TSK_ExplicitInstantiationDefinition:
-      return llvm::GlobalVariable::WeakODRLinkage;
+    return NonDiscardableODRLinkage;
   }
 
   llvm_unreachable("Invalid TemplateSpecializationKind!");
diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h
index e1554be..69cf079 100644
--- a/lib/CodeGen/CGVTables.h
+++ b/lib/CodeGen/CGVTables.h
@@ -61,11 +61,10 @@
   /// decl.
   /// \param Components - The vtable components; this is really an array of
   /// VTableComponents.
-  llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
-                                          const VTableComponent *Components, 
-                                          unsigned NumComponents,
-                                const VTableLayout::VTableThunkTy *VTableThunks,
-                                          unsigned NumVTableThunks);
+  llvm::Constant *CreateVTableInitializer(
+      const CXXRecordDecl *RD, const VTableComponent *Components,
+      unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
+      unsigned NumVTableThunks, llvm::Constant *RTTI);
 
   CodeGenVTables(CodeGenModule &CGM);
 
@@ -99,7 +98,7 @@
                              VTableAddressPointsMapTy& AddressPoints);
 
     
-  /// GetAddrOfVTable - Get the address of the VTT for the given record decl.
+  /// GetAddrOfVTT - Get the address of the VTT for the given record decl.
   llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
 
   /// EmitVTTDefinition - Emit the definition of the given vtable.
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 4b7d51b..2bf82e8 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -13,7 +13,6 @@
   ScalarOpts
   Support
   Target
-  TransformUtils
   )
 
 add_clang_library(clangCodeGen
@@ -45,7 +44,6 @@
   CGObjCRuntime.cpp
   CGOpenCLRuntime.cpp
   CGOpenMPRuntime.cpp
-  CGRTTI.cpp
   CGRecordLayoutBuilder.cpp
   CGStmt.cpp
   CGStmtOpenMP.cpp
@@ -60,8 +58,8 @@
   CodeGenTypes.cpp
   ItaniumCXXABI.cpp
   MicrosoftCXXABI.cpp
-  MicrosoftRTTI.cpp
   ModuleBuilder.cpp
+  SanitizerBlacklist.cpp
   TargetInfo.cpp
 
   DEPENDS
diff --git a/lib/CodeGen/CodeGenABITypes.cpp b/lib/CodeGen/CodeGenABITypes.cpp
index fba7184..180cd51 100644
--- a/lib/CodeGen/CodeGenABITypes.cpp
+++ b/lib/CodeGen/CodeGenABITypes.cpp
@@ -61,7 +61,7 @@
 
 const CGFunctionInfo &
 CodeGenABITypes::arrangeFreeFunctionCall(CanQualType returnType,
-                                         llvm::ArrayRef<CanQualType> argTypes,
+                                         ArrayRef<CanQualType> argTypes,
                                          FunctionType::ExtInfo info,
                                          RequiredArgs args) {
   return CGM->getTypes().arrangeLLVMFunctionInfo(
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
index 2fe9842..0f63759 100644
--- a/lib/CodeGen/CodeGenAction.cpp
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -235,11 +235,18 @@
     /// \return True if the diagnostic has been successfully reported, false
     /// otherwise.
     bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
-    /// \brief Specialized handler for the optimization diagnostic.
-    /// Note that this handler only accepts remarks and it always handles
+    /// \brief Specialized handlers for optimization remarks.
+    /// Note that these handlers only accept remarks and they always handle
     /// them.
     void
+    EmitOptimizationRemark(const llvm::DiagnosticInfoOptimizationRemarkBase &D,
+                           unsigned DiagID);
+    void
     OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D);
+    void OptimizationRemarkHandler(
+        const llvm::DiagnosticInfoOptimizationRemarkMissed &D);
+    void OptimizationRemarkHandler(
+        const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D);
   };
   
   void BackendConsumer::anchor() {}
@@ -260,13 +267,15 @@
   LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
 
   // Create the copy and transfer ownership to clang::SourceManager.
+  // TODO: Avoid copying files into memory.
   llvm::MemoryBuffer *CBuf =
   llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
                                        LBuf->getBufferIdentifier());
+  // FIXME: Keep a file ID map instead of creating new IDs for each location.
   FileID FID = CSM.createFileID(CBuf);
 
   // Translate the offset into the file.
-  unsigned Offset = D.getLoc().getPointer()  - LBuf->getBufferStart();
+  unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
   SourceLocation NewLoc =
   CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset);
   return FullSourceLoc(NewLoc, CSM);
@@ -290,13 +299,24 @@
   FullSourceLoc Loc;
   if (D.getLoc() != SMLoc())
     Loc = ConvertBackendLocation(D, Context->getSourceManager());
-  
 
+  unsigned DiagID;
+  switch (D.getKind()) {
+  case llvm::SourceMgr::DK_Error:
+    DiagID = diag::err_fe_inline_asm;
+    break;
+  case llvm::SourceMgr::DK_Warning:
+    DiagID = diag::warn_fe_inline_asm;
+    break;
+  case llvm::SourceMgr::DK_Note:
+    DiagID = diag::note_fe_inline_asm;
+    break;
+  }
   // If this problem has clang-level source location information, report the
-  // issue as being an error in the source with a note showing the instantiated
+  // issue in the source with a note showing the instantiated
   // code.
   if (LocCookie.isValid()) {
-    Diags.Report(LocCookie, diag::err_fe_inline_asm).AddString(Message);
+    Diags.Report(LocCookie, DiagID).AddString(Message);
     
     if (D.getLoc().isValid()) {
       DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
@@ -312,10 +332,10 @@
     return;
   }
   
-  // Otherwise, report the backend error as occurring in the generated .s file.
-  // If Loc is invalid, we still need to report the error, it just gets no
+  // Otherwise, report the backend issue as occurring in the generated .s file.
+  // If Loc is invalid, we still need to report the issue, it just gets no
   // location info.
-  Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message);
+  Diags.Report(Loc, DiagID).AddString(Message);
 }
 
 #define ComputeDiagID(Severity, GroupName, DiagID)                             \
@@ -386,57 +406,83 @@
     // We do not know how to format other severities.
     return false;
 
-  // FIXME: We should demangle the function name.
-  // FIXME: Is there a way to get a location for that function?
-  FullSourceLoc Loc;
-  Diags.Report(Loc, diag::warn_fe_backend_frame_larger_than)
-      << D.getStackSize() << D.getFunction().getName();
-  return true;
+  if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) {
+    Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()),
+                 diag::warn_fe_frame_larger_than)
+        << D.getStackSize() << Decl::castToDeclContext(ND);
+    return true;
+  }
+
+  return false;
+}
+
+void BackendConsumer::EmitOptimizationRemark(
+    const llvm::DiagnosticInfoOptimizationRemarkBase &D, unsigned DiagID) {
+  // We only support remarks.
+  assert(D.getSeverity() == llvm::DS_Remark);
+
+  SourceManager &SourceMgr = Context->getSourceManager();
+  FileManager &FileMgr = SourceMgr.getFileManager();
+  StringRef Filename;
+  unsigned Line, Column;
+  D.getLocation(&Filename, &Line, &Column);
+  SourceLocation DILoc;
+  const FileEntry *FE = FileMgr.getFile(Filename);
+  if (FE && Line > 0) {
+    // If -gcolumn-info was not used, Column will be 0. This upsets the
+    // source manager, so pass 1 if Column is not set.
+    DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
+  }
+
+  // If a location isn't available, try to approximate it using the associated
+  // function definition. We use the definition's right brace to differentiate
+  // from diagnostics that genuinely relate to the function itself.
+  FullSourceLoc Loc(DILoc, SourceMgr);
+  if (Loc.isInvalid())
+    if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
+      Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace());
+
+  Diags.Report(Loc, DiagID) << AddFlagValue(D.getPassName())
+                            << D.getMsg().str();
+
+  if (DILoc.isInvalid())
+    // If we were not able to translate the file:line:col information
+    // back to a SourceLocation, at least emit a note stating that
+    // we could not translate this location. This can happen in the
+    // case of #line directives.
+    Diags.Report(Loc, diag::note_fe_backend_optimization_remark_invalid_loc)
+        << Filename << Line << Column;
 }
 
 void BackendConsumer::OptimizationRemarkHandler(
     const llvm::DiagnosticInfoOptimizationRemark &D) {
-  // We only support remarks.
-  assert(D.getSeverity() == llvm::DS_Remark);
-
-  // Optimization remarks are active only if -Rpass=regexp is given and the
-  // regular expression pattern in 'regexp' matches the name of the pass
-  // name in \p D.
+  // Optimization remarks are active only if the -Rpass flag has a regular
+  // expression that matches the name of the pass name in \p D.
   if (CodeGenOpts.OptimizationRemarkPattern &&
-      CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName())) {
-    SourceManager &SourceMgr = Context->getSourceManager();
-    FileManager &FileMgr = SourceMgr.getFileManager();
-    StringRef Filename;
-    unsigned Line, Column;
-    D.getLocation(&Filename, &Line, &Column);
-    SourceLocation Loc;
-    const FileEntry *FE = FileMgr.getFile(Filename);
-    if (FE && Line > 0) {
-      // If -gcolumn-info was not used, Column will be 0. This upsets the
-      // source manager, so if Column is not set, set it to 1.
-      if (Column == 0)
-        Column = 1;
-      Loc = SourceMgr.translateFileLineCol(FE, Line, Column);
-    }
-    Diags.Report(Loc, diag::remark_fe_backend_optimization_remark)
-        << AddFlagValue(D.getPassName()) << D.getMsg().str();
+      CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName()))
+    EmitOptimizationRemark(D, diag::remark_fe_backend_optimization_remark);
+}
 
-    if (Line == 0)
-      // If we could not extract a source location for the diagnostic,
-      // inform the user how they can get source locations back.
-      //
-      // FIXME: We should really be generating !srcloc annotations when
-      // -Rpass is used. !srcloc annotations need to be emitted in
-      // approximately the same spots as !dbg nodes.
-      Diags.Report(diag::note_fe_backend_optimization_remark_missing_loc);
-    else if (Loc.isInvalid())
-      // If we were not able to translate the file:line:col information
-      // back to a SourceLocation, at least emit a note stating that
-      // we could not translate this location. This can happen in the
-      // case of #line directives.
-      Diags.Report(diag::note_fe_backend_optimization_remark_invalid_loc)
-        << Filename << Line << Column;
-  }
+void BackendConsumer::OptimizationRemarkHandler(
+    const llvm::DiagnosticInfoOptimizationRemarkMissed &D) {
+  // Missed optimization remarks are active only if the -Rpass-missed
+  // flag has a regular expression that matches the name of the pass
+  // name in \p D.
+  if (CodeGenOpts.OptimizationRemarkMissedPattern &&
+      CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName()))
+    EmitOptimizationRemark(D,
+                           diag::remark_fe_backend_optimization_remark_missed);
+}
+
+void BackendConsumer::OptimizationRemarkHandler(
+    const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D) {
+  // Optimization analysis remarks are active only if the -Rpass-analysis
+  // flag has a regular expression that matches the name of the pass
+  // name in \p D.
+  if (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
+      CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))
+    EmitOptimizationRemark(
+        D, diag::remark_fe_backend_optimization_remark_analysis);
 }
 
 /// \brief This function is invoked when the backend needs
@@ -461,6 +507,17 @@
     // handler. There is no generic way of emitting them.
     OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI));
     return;
+  case llvm::DK_OptimizationRemarkMissed:
+    // Optimization remarks are always handled completely by this
+    // handler. There is no generic way of emitting them.
+    OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemarkMissed>(DI));
+    return;
+  case llvm::DK_OptimizationRemarkAnalysis:
+    // Optimization remarks are always handled completely by this
+    // handler. There is no generic way of emitting them.
+    OptimizationRemarkHandler(
+        cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI));
+    return;
   default:
     // Plugin IDs are not bound to any value as they are set dynamically.
     ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
@@ -525,6 +582,7 @@
   case Backend_EmitNothing:
     return nullptr;
   case Backend_EmitMCNull:
+    return CI.createNullOutputFile();
   case Backend_EmitObj:
     return CI.createDefaultOutputFile(true, InFile, "o");
   }
@@ -557,7 +615,7 @@
 
     ErrorOr<llvm::Module *> ModuleOrErr =
         getLazyBitcodeModule(BCBuf, *VMContext);
-    if (error_code EC = ModuleOrErr.getError()) {
+    if (std::error_code EC = ModuleOrErr.getError()) {
       CI.getDiagnostics().Report(diag::err_cannot_open_file)
         << LinkBCFile << EC.message();
       return nullptr;
@@ -565,12 +623,9 @@
     LinkModuleToUse = ModuleOrErr.get();
   }
 
-  StringRef MainFileName = getCompilerInstance().getCodeGenOpts().MainFileName;
-  if (MainFileName.empty())
-    MainFileName = InFile;
   BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(), CI.getCodeGenOpts(),
                                    CI.getTargetOpts(), CI.getLangOpts(),
-                                   CI.getFrontendOpts().ShowTimers, MainFileName,
+                                   CI.getFrontendOpts().ShowTimers, InFile,
                                    LinkModuleToUse, OS.release(), *VMContext);
   return BEConsumer;
 }
@@ -586,23 +641,23 @@
 
     bool Invalid;
     SourceManager &SM = CI.getSourceManager();
-    const llvm::MemoryBuffer *MainFile = SM.getBuffer(SM.getMainFileID(),
-                                                      &Invalid);
+    FileID FID = SM.getMainFileID();
+    llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid);
     if (Invalid)
       return;
 
-    // FIXME: This is stupid, IRReader shouldn't take ownership.
-    llvm::MemoryBuffer *MainFileCopy =
-      llvm::MemoryBuffer::getMemBufferCopy(MainFile->getBuffer(),
-                                           getCurrentFile());
-
     llvm::SMDiagnostic Err;
-    TheModule.reset(ParseIR(MainFileCopy, Err, *VMContext));
+    TheModule.reset(ParseIR(MainFile, Err, *VMContext));
     if (!TheModule) {
-      // Translate from the diagnostic info to the SourceManager location.
-      SourceLocation Loc = SM.translateFileLineCol(
-        SM.getFileEntryForID(SM.getMainFileID()), Err.getLineNo(),
-        Err.getColumnNo() + 1);
+      // Translate from the diagnostic info to the SourceManager location if
+      // available.
+      // TODO: Unify this with ConvertBackendLocation()
+      SourceLocation Loc;
+      if (Err.getLineNo() > 0) {
+        assert(Err.getColumnNo() >= 0);
+        Loc = SM.translateFileLineCol(SM.getFileEntryForID(FID),
+                                      Err.getLineNo(), Err.getColumnNo() + 1);
+      }
 
       // Strip off a leading diagnostic code if there is one.
       StringRef Msg = Err.getMessage();
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 7de619e..0987673 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -37,11 +37,7 @@
     : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
       Builder(cgm.getModule().getContext(), llvm::ConstantFolder(),
               CGBuilderInserterTy(this)), CapturedStmtInfo(nullptr),
-      SanitizePerformTypeCheck(CGM.getSanOpts().Null |
-                               CGM.getSanOpts().Alignment |
-                               CGM.getSanOpts().ObjectSize |
-                               CGM.getSanOpts().Vptr),
-      SanOpts(&CGM.getSanOpts()), AutoreleaseResult(false), BlockInfo(nullptr),
+      SanOpts(&CGM.getLangOpts().Sanitize), AutoreleaseResult(false), BlockInfo(nullptr),
       BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
       NormalCleanupDest(nullptr), NextCleanupDestIndex(1),
       FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
@@ -539,10 +535,8 @@
   CurFnInfo = &FnInfo;
   assert(CurFn->isDeclaration() && "Function already has body?");
 
-  if (CGM.getSanitizerBlacklist().isIn(*Fn)) {
+  if (CGM.getSanitizerBlacklist().isIn(*Fn))
     SanOpts = &SanitizerOptions::Disabled;
-    SanitizePerformTypeCheck = false;
-  }
 
   // Pass inline keyword to optimizer if it appears explicitly on any
   // declaration. Also, in the case of -fno-inline attach NoInline
@@ -794,16 +788,13 @@
   // of the declaration as the location for the subprogram. A function
   // may lack a declaration in the source code if it is created by code
   // gen. (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
-  SourceLocation Loc;
-  if (FD) {
-    Loc = FD->getLocation();
+  SourceLocation Loc = FD->getLocation();
 
-    // If this is a function specialization then use the pattern body
-    // as the location for the function.
-    if (const FunctionDecl *SpecDecl = FD->getTemplateInstantiationPattern())
-      if (SpecDecl->hasBody(SpecDecl))
-        Loc = SpecDecl->getLocation();
-  }
+  // If this is a function specialization then use the pattern body
+  // as the location for the function.
+  if (const FunctionDecl *SpecDecl = FD->getTemplateInstantiationPattern())
+    if (SpecDecl->hasBody(SpecDecl))
+      Loc = SpecDecl->getLocation();
 
   // Emit the standard function prologue.
   StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 750bec8..c04fc3e 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -231,10 +231,6 @@
   /// potentially higher performance penalties.
   unsigned char BoundsChecking;
 
-  /// \brief Whether any type-checking sanitizers are enabled. If \c false,
-  /// calls to EmitTypeCheck can be skipped.
-  bool SanitizePerformTypeCheck;
-
   /// \brief Sanitizer options to use for this function.
   const SanitizerOptions *SanOpts;
 
@@ -1647,7 +1643,8 @@
                              llvm::Value *This);
 
   void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType,
-                               llvm::Value *NewPtr, llvm::Value *NumElements);
+                               llvm::Value *NewPtr, llvm::Value *NumElements,
+                               llvm::Value *AllocSizeWithoutCookie);
 
   void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,
                         llvm::Value *Ptr);
@@ -1658,6 +1655,9 @@
   void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr,
                       QualType DeleteTy);
 
+  RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
+                                  const Expr *Arg, bool IsDelete);
+
   llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
   llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);
   llvm::Value* EmitCXXUuidofExpr(const CXXUuidofExpr *E);
@@ -1689,6 +1689,10 @@
     TCK_DowncastReference
   };
 
+  /// \brief Whether any type-checking sanitizers are enabled. If \c false,
+  /// calls to EmitTypeCheck can be skipped.
+  bool sanitizePerformTypeCheck() const;
+
   /// \brief Emit a check that \p V is the address of storage of the
   /// appropriate size and alignment for an object of type \p Type.
   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V,
@@ -1856,9 +1860,14 @@
   void EmitGotoStmt(const GotoStmt &S);
   void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
   void EmitIfStmt(const IfStmt &S);
-  void EmitWhileStmt(const WhileStmt &S);
-  void EmitDoStmt(const DoStmt &S);
-  void EmitForStmt(const ForStmt &S);
+
+  void EmitCondBrHints(llvm::LLVMContext &Context, llvm::BranchInst *CondBr,
+                       const ArrayRef<const Attr *> &Attrs);
+  void EmitWhileStmt(const WhileStmt &S,
+                     const ArrayRef<const Attr *> &Attrs = None);
+  void EmitDoStmt(const DoStmt &S, const ArrayRef<const Attr *> &Attrs = None);
+  void EmitForStmt(const ForStmt &S,
+                   const ArrayRef<const Attr *> &Attrs = None);
   void EmitReturnStmt(const ReturnStmt &S);
   void EmitDeclStmt(const DeclStmt &S);
   void EmitBreakStmt(const BreakStmt &S);
@@ -1875,23 +1884,27 @@
   void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S);
   void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S);
 
-  llvm::Constant *getUnwindResumeFn();
-  llvm::Constant *getUnwindResumeOrRethrowFn();
   void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
   void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
 
   void EmitCXXTryStmt(const CXXTryStmt &S);
   void EmitSEHTryStmt(const SEHTryStmt &S);
-  void EmitCXXForRangeStmt(const CXXForRangeStmt &S);
+  void EmitSEHLeaveStmt(const SEHLeaveStmt &S);
+  void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
+                           const ArrayRef<const Attr *> &Attrs = None);
 
   llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
-  llvm::Function *GenerateCapturedStmtFunction(const CapturedDecl *CD,
-                                               const RecordDecl *RD,
-                                               SourceLocation Loc);
+  llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S);
   llvm::Value *GenerateCapturedStmtArgument(const CapturedStmt &S);
 
   void EmitOMPParallelDirective(const OMPParallelDirective &S);
   void EmitOMPSimdDirective(const OMPSimdDirective &S);
+  void EmitOMPForDirective(const OMPForDirective &S);
+  void EmitOMPSectionsDirective(const OMPSectionsDirective &S);
+  void EmitOMPSectionDirective(const OMPSectionDirective &S);
+  void EmitOMPSingleDirective(const OMPSingleDirective &S);
+  void EmitOMPParallelForDirective(const OMPParallelForDirective &S);
+  void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S);
 
   //===--------------------------------------------------------------------===//
   //                         LValue Expression Emission
@@ -2223,9 +2236,6 @@
                                    bool negateForRightShift);
   llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt,
                                  llvm::Type *Ty, bool usgn, const char *name);
-  llvm::Value *EmitConcatVectors(llvm::Value *Lo, llvm::Value *Hi,
-                                 llvm::Type *ArgTy);
-  llvm::Value *EmitExtractHigh(llvm::Value *In, llvm::Type *ResTy);
   // Helper functions for EmitAArch64BuiltinExpr.
   llvm::Value *vectorWrapScalar8(llvm::Value *Op);
   llvm::Value *vectorWrapScalar16(llvm::Value *Op);
@@ -2241,6 +2251,7 @@
   llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops);
   llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
   llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+  llvm::Value *EmitR600BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
 
   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
@@ -2300,7 +2311,7 @@
   llvm::Value *EmitARCRetainScalarExpr(const Expr *expr);
   llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr);
 
-  void EmitARCIntrinsicUse(llvm::ArrayRef<llvm::Value*> values);
+  void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values);
 
   static Destroyer destroyARCStrongImprecise;
   static Destroyer destroyARCStrongPrecise;
@@ -2640,7 +2651,8 @@
 
   void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes,
                     CallExpr::const_arg_iterator ArgBeg,
-                    CallExpr::const_arg_iterator ArgEnd, bool ForceColumnInfo);
+                    CallExpr::const_arg_iterator ArgEnd,
+                    bool ForceColumnInfo = false);
 
 private:
   const TargetCodeGenInfo &getTargetHooks() const {
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index c55e231..d0563b2 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -87,11 +87,8 @@
       NSConcreteStackBlock(nullptr), BlockObjectAssign(nullptr),
       BlockObjectDispose(nullptr), BlockDescriptorType(nullptr),
       GenericBlockLiteralType(nullptr), LifetimeStartFn(nullptr),
-      LifetimeEndFn(nullptr),
-      SanitizerBlacklist(
-          llvm::SpecialCaseList::createOrDie(CGO.SanitizerBlacklistFile)),
-      SanOpts(SanitizerBlacklist->isIn(M) ? SanitizerOptions::Disabled
-                                          : LangOpts.Sanitize) {
+      LifetimeEndFn(nullptr), SanitizerBL(llvm::SpecialCaseList::createOrDie(
+                                  CGO.SanitizerBlacklistFile)) {
 
   // Initialize the type cache.
   llvm::LLVMContext &LLVMContext = M.getContext();
@@ -122,7 +119,7 @@
     createCUDARuntime();
 
   // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
-  if (SanOpts.Thread ||
+  if (LangOpts.Sanitize.Thread ||
       (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
     TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(),
                            getCXXABI().getMangleContext());
@@ -141,7 +138,7 @@
   RRData = new RREntrypoints();
 
   if (!CodeGenOpts.InstrProfileInput.empty()) {
-    if (llvm::error_code EC = llvm::IndexedInstrProfReader::create(
+    if (std::error_code EC = llvm::IndexedInstrProfReader::create(
             CodeGenOpts.InstrProfileInput, PGOReader)) {
       unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
                                               "Could not read profile: %0");
@@ -225,6 +222,25 @@
   }
 }
 
+// This is only used in aliases that we created and we know they have a
+// linear structure.
+static const llvm::GlobalObject *getAliasedGlobal(const llvm::GlobalAlias &GA) {
+  llvm::SmallPtrSet<const llvm::GlobalAlias*, 4> Visited;
+  const llvm::Constant *C = &GA;
+  for (;;) {
+    C = C->stripPointerCasts();
+    if (auto *GO = dyn_cast<llvm::GlobalObject>(C))
+      return GO;
+    // stripPointerCasts will not walk over weak aliases.
+    auto *GA2 = dyn_cast<llvm::GlobalAlias>(C);
+    if (!GA2)
+      return nullptr;
+    if (!Visited.insert(GA2))
+      return nullptr;
+    C = GA2->getAliasee();
+  }
+}
+
 void CodeGenModule::checkAliases() {
   // Check if the constructed aliases are well formed. It is really unfortunate
   // that we have to do this in CodeGen, but we only construct mangled names
@@ -239,19 +255,43 @@
     StringRef MangledName = getMangledName(GD);
     llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
     auto *Alias = cast<llvm::GlobalAlias>(Entry);
-    llvm::GlobalValue *GV = Alias->getAliasee();
-    if (GV->isDeclaration()) {
+    const llvm::GlobalValue *GV = getAliasedGlobal(*Alias);
+    if (!GV) {
+      Error = true;
+      Diags.Report(AA->getLocation(), diag::err_cyclic_alias);
+    } else if (GV->isDeclaration()) {
       Error = true;
       Diags.Report(AA->getLocation(), diag::err_alias_to_undefined);
     }
 
-    llvm::GlobalObject *Aliasee = Alias->getAliasee();
+    llvm::Constant *Aliasee = Alias->getAliasee();
+    llvm::GlobalValue *AliaseeGV;
+    if (auto CE = dyn_cast<llvm::ConstantExpr>(Aliasee))
+      AliaseeGV = cast<llvm::GlobalValue>(CE->getOperand(0));
+    else
+      AliaseeGV = cast<llvm::GlobalValue>(Aliasee);
+
     if (const SectionAttr *SA = D->getAttr<SectionAttr>()) {
       StringRef AliasSection = SA->getName();
-      if (AliasSection != Aliasee->getSection())
+      if (AliasSection != AliaseeGV->getSection())
         Diags.Report(SA->getLocation(), diag::warn_alias_with_section)
             << AliasSection;
     }
+
+    // We have to handle alias to weak aliases in here. LLVM itself disallows
+    // this since the object semantics would not match the IL one. For
+    // compatibility with gcc we implement it by just pointing the alias
+    // to its aliasee's aliasee. We also warn, since the user is probably
+    // expecting the link to be weak.
+    if (auto GA = dyn_cast<llvm::GlobalAlias>(AliaseeGV)) {
+      if (GA->mayBeOverridden()) {
+        Diags.Report(AA->getLocation(), diag::warn_alias_to_weak_alias)
+            << GV->getName() << GA->getName();
+        Aliasee = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
+            GA->getAliasee(), Alias->getType());
+        Alias->setAliasee(Aliasee);
+      }
+    }
   }
   if (!Error)
     return;
@@ -271,6 +311,19 @@
   DeferredDeclsToEmit.clear();
 }
 
+void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags,
+                                       StringRef MainFile) {
+  if (!hasDiagnostics())
+    return;
+  if (VisitedInMainFile > 0 && VisitedInMainFile == MissingInMainFile) {
+    if (MainFile.empty())
+      MainFile = "<stdin>";
+    Diags.Report(diag::warn_profile_data_unprofiled) << MainFile;
+  } else
+    Diags.Report(diag::warn_profile_data_out_of_date) << Visited << Missing
+                                                      << Mismatched;
+}
+
 void CodeGenModule::Release() {
   EmitDeferred();
   applyReplacements();
@@ -284,9 +337,8 @@
   if (getCodeGenOpts().ProfileInstrGenerate)
     if (llvm::Function *PGOInit = CodeGenPGO::emitInitialization(*this))
       AddGlobalCtor(PGOInit, 0);
-  if (PGOReader && PGOStats.isOutOfDate())
-    getDiags().Report(diag::warn_profile_data_out_of_date)
-        << PGOStats.Visited << PGOStats.Missing << PGOStats.Mismatched;
+  if (PGOReader && PGOStats.hasDiagnostics())
+    PGOStats.reportDiagnostics(getDiags(), getCodeGenOpts().MainFileName);
   EmitCtorList(GlobalCtors, "llvm.global_ctors");
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitGlobalAnnotations();
@@ -309,6 +361,23 @@
     getModule().addModuleFlag(llvm::Module::Warning, "Debug Info Version",
                               llvm::DEBUG_METADATA_VERSION);
 
+  // We need to record the widths of enums and wchar_t, so that we can generate
+  // the correct build attributes in the ARM backend.
+  llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
+  if (   Arch == llvm::Triple::arm
+      || Arch == llvm::Triple::armeb
+      || Arch == llvm::Triple::thumb
+      || Arch == llvm::Triple::thumbeb) {
+    // Width of wchar_t in bytes
+    uint64_t WCharWidth =
+        Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity();
+    getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth);
+
+    // The minimum width of an enum in bytes
+    uint64_t EnumWidth = Context.getLangOpts().ShortEnums ? 1 : 4;
+    getModule().addModuleFlag(llvm::Module::Error, "min_enum_size", EnumWidth);
+  }
+
   SimplifyPersonality();
 
   if (getCodeGenOpts().EmitDeclMetadata)
@@ -321,6 +390,8 @@
     DebugInfo->finalize();
 
   EmitVersionIdentMetadata();
+
+  EmitTargetMetadata();
 }
 
 void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
@@ -455,45 +526,40 @@
 }
 
 StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
+  StringRef &FoundStr = MangledDeclNames[GD.getCanonicalDecl()];
+  if (!FoundStr.empty())
+    return FoundStr;
+
   const auto *ND = cast<NamedDecl>(GD.getDecl());
-
-  StringRef &Str = MangledDeclNames[GD.getCanonicalDecl()];
-  if (!Str.empty())
-    return Str;
-
-  if (!getCXXABI().getMangleContext().shouldMangleDeclName(ND)) {
+  SmallString<256> Buffer;
+  StringRef Str;
+  if (getCXXABI().getMangleContext().shouldMangleDeclName(ND)) {
+    llvm::raw_svector_ostream Out(Buffer);
+    if (const auto *D = dyn_cast<CXXConstructorDecl>(ND))
+      getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out);
+    else if (const auto *D = dyn_cast<CXXDestructorDecl>(ND))
+      getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out);
+    else
+      getCXXABI().getMangleContext().mangleName(ND, Out);
+    Str = Out.str();
+  } else {
     IdentifierInfo *II = ND->getIdentifier();
     assert(II && "Attempt to mangle unnamed decl.");
-
     Str = II->getName();
-    return Str;
   }
-  
-  SmallString<256> Buffer;
-  llvm::raw_svector_ostream Out(Buffer);
-  if (const auto *D = dyn_cast<CXXConstructorDecl>(ND))
-    getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out);
-  else if (const auto *D = dyn_cast<CXXDestructorDecl>(ND))
-    getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out);
-  else
-    getCXXABI().getMangleContext().mangleName(ND, Out);
 
-  // Allocate space for the mangled name.
-  Out.flush();
-  size_t Length = Buffer.size();
-  char *Name = MangledNamesAllocator.Allocate<char>(Length);
-  std::copy(Buffer.begin(), Buffer.end(), Name);
-  
-  Str = StringRef(Name, Length);
-  
-  return Str;
+  auto &Mangled = Manglings.GetOrCreateValue(Str);
+  Mangled.second = GD;
+  return FoundStr = Mangled.first();
 }
 
-void CodeGenModule::getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
-                                        const BlockDecl *BD) {
+StringRef CodeGenModule::getBlockMangledName(GlobalDecl GD,
+                                             const BlockDecl *BD) {
   MangleContext &MangleCtx = getCXXABI().getMangleContext();
   const Decl *D = GD.getDecl();
-  llvm::raw_svector_ostream Out(Buffer.getBuffer());
+
+  SmallString<256> Buffer;
+  llvm::raw_svector_ostream Out(Buffer);
   if (!D)
     MangleCtx.mangleGlobalBlock(BD, 
       dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out);
@@ -503,6 +569,10 @@
     MangleCtx.mangleDtorBlock(DD, GD.getDtorType(), BD, Out);
   else
     MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Out);
+
+  auto &Mangled = Manglings.GetOrCreateValue(Out.str());
+  Mangled.second = BD;
+  return Mangled.first();
 }
 
 llvm::GlobalValue *CodeGenModule::GetGlobalValue(StringRef Name) {
@@ -521,7 +591,7 @@
 /// when the module is unloaded.
 void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority) {
   // FIXME: Type coercion of void()* types.
-  GlobalDtors.push_back(Structor(Priority, Dtor, 0));
+  GlobalDtors.push_back(Structor(Priority, Dtor, nullptr));
 }
 
 void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
@@ -659,17 +729,16 @@
     B.addAttribute(llvm::Attribute::StackProtectReq);
 
   // Add sanitizer attributes if function is not blacklisted.
-  if (!SanitizerBlacklist->isIn(*F)) {
+  if (!SanitizerBL.isIn(*F)) {
     // When AddressSanitizer is enabled, set SanitizeAddress attribute
     // unless __attribute__((no_sanitize_address)) is used.
-    if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>())
+    if (LangOpts.Sanitize.Address && !D->hasAttr<NoSanitizeAddressAttr>())
       B.addAttribute(llvm::Attribute::SanitizeAddress);
     // Same for ThreadSanitizer and __attribute__((no_sanitize_thread))
-    if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) {
+    if (LangOpts.Sanitize.Thread && !D->hasAttr<NoSanitizeThreadAttr>())
       B.addAttribute(llvm::Attribute::SanitizeThread);
-    }
     // Same for MemorySanitizer and __attribute__((no_sanitize_memory))
-    if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
+    if (LangOpts.Sanitize.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
       B.addAttribute(llvm::Attribute::SanitizeMemory);
   }
 
@@ -1415,7 +1484,7 @@
     // This is the first use or definition of a mangled name.  If there is a
     // deferred decl with this name, remember that we need to emit it at the end
     // of the file.
-    llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
+    auto DDI = DeferredDecls.find(MangledName);
     if (DDI != DeferredDecls.end()) {
       // Move the potentially referenced deferred decl to the
       // DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
@@ -1463,8 +1532,6 @@
     }
   }
 
-  getTargetCodeGenInfo().emitTargetMD(D, F, *this);
-
   // Make sure the result is of the requested type.
   if (!IsIncompleteFunction) {
     assert(F->getType()->getElementType() == Ty);
@@ -1575,7 +1642,7 @@
   // This is the first use or definition of a mangled name.  If there is a
   // deferred decl with this name, remember that we need to emit it at the end
   // of the file.
-  llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
+  auto DDI = DeferredDecls.find(MangledName);
   if (DDI != DeferredDecls.end()) {
     // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
     // list, and remove it from DeferredDecls (since we don't need it anymore).
@@ -1614,8 +1681,6 @@
   if (AddrSpace != Ty->getAddressSpace())
     return llvm::ConstantExpr::getAddrSpaceCast(GV, Ty);
 
-  getTargetCodeGenInfo().emitTargetMD(D, GV, *this);
-
   return GV;
 }
 
@@ -1861,6 +1926,16 @@
   // Set the llvm linkage type as appropriate.
   llvm::GlobalValue::LinkageTypes Linkage =
       getLLVMLinkageVarDefinition(D, GV->isConstant());
+
+  // On Darwin, the backing variable for a C++11 thread_local variable always
+  // has internal linkage; all accesses should just be calls to the
+  // Itanium-specified entry point, which has the normal linkage of the
+  // variable.
+  if (const auto *VD = dyn_cast<VarDecl>(D))
+    if (!VD->isStaticLocal() && VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+        Context.getTargetInfo().getTriple().isMacOSX())
+      Linkage = llvm::GlobalValue::InternalLinkage;
+
   GV->setLinkage(Linkage);
   if (D->hasAttr<DLLImportAttr>())
     GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
@@ -1877,17 +1952,7 @@
   if (NeedsGlobalCtor || NeedsGlobalDtor)
     EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
 
-  // If we are compiling with ASan, add metadata indicating dynamically
-  // initialized globals.
-  if (SanOpts.Address && NeedsGlobalCtor) {
-    llvm::Module &M = getModule();
-
-    llvm::NamedMDNode *DynamicInitializers =
-        M.getOrInsertNamedMetadata("llvm.asan.dynamically_initialized_globals");
-    llvm::Value *GlobalToAdd[] = { GV };
-    llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalToAdd);
-    DynamicInitializers->addOperand(ThisGlobal);
-  }
+  reportGlobalToASan(GV, D->getLocation(), NeedsGlobalCtor);
 
   // Emit global variable debug information.
   if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -1895,6 +1960,51 @@
       DI->EmitGlobalVariable(GV, D);
 }
 
+void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
+                                       SourceLocation Loc, bool IsDynInit) {
+  if (!LangOpts.Sanitize.Address)
+    return;
+  IsDynInit &= !SanitizerBL.isIn(*GV, "init");
+  bool IsBlacklisted = SanitizerBL.isIn(*GV);
+
+  llvm::LLVMContext &LLVMCtx = TheModule.getContext();
+
+  llvm::GlobalVariable *LocDescr = nullptr;
+  if (!IsBlacklisted) {
+    // Don't generate source location if a global is blacklisted - it won't
+    // be instrumented anyway.
+    PresumedLoc PLoc = Context.getSourceManager().getPresumedLoc(Loc);
+    if (PLoc.isValid()) {
+      llvm::Constant *LocData[] = {
+          GetAddrOfConstantCString(PLoc.getFilename()),
+          llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx), PLoc.getLine()),
+          llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx),
+                                 PLoc.getColumn()),
+      };
+      auto LocStruct = llvm::ConstantStruct::getAnon(LocData);
+      LocDescr = new llvm::GlobalVariable(TheModule, LocStruct->getType(), true,
+                                          llvm::GlobalValue::PrivateLinkage,
+                                          LocStruct, ".asan_loc_descr");
+      LocDescr->setUnnamedAddr(true);
+      // Add LocDescr to llvm.compiler.used, so that it won't be removed by
+      // the optimizer before the ASan instrumentation pass.
+      addCompilerUsedGlobal(LocDescr);
+    }
+  }
+
+  llvm::Value *GlobalMetadata[] = {
+      GV,
+      LocDescr,
+      llvm::ConstantInt::get(llvm::Type::getInt1Ty(LLVMCtx), IsDynInit),
+      llvm::ConstantInt::get(llvm::Type::getInt1Ty(LLVMCtx), IsBlacklisted)
+  };
+
+  llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata);
+  llvm::NamedMDNode *AsanGlobals =
+      TheModule.getOrInsertNamedMetadata("llvm.asan.globals");
+  AsanGlobals->addOperand(ThisGlobal);
+}
+
 static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
   // Don't give variables common linkage if -fno-common was specified unless it
   // was overridden by a NoCommon attribute.
@@ -1965,10 +2075,15 @@
 
   // If required by the ABI, give definitions of static data members with inline
   // initializers at least linkonce_odr linkage.
+  auto const VD = dyn_cast<VarDecl>(D);
   if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() &&
-      isa<VarDecl>(D) &&
-      isVarDeclInlineInitializedStaticDataMember(cast<VarDecl>(D)))
+      VD && isVarDeclInlineInitializedStaticDataMember(VD)) {
+    if (VD->hasAttr<DLLImportAttr>())
+      return llvm::GlobalValue::AvailableExternallyLinkage;
+    if (VD->hasAttr<DLLExportAttr>())
+      return llvm::GlobalValue::WeakODRLinkage;
     return llvm::GlobalValue::LinkOnceODRLinkage;
+  }
 
   // C++ doesn't have tentative definitions and thus cannot have common
   // linkage.
@@ -2220,29 +2335,6 @@
     AddGlobalAnnotations(D, Fn);
 }
 
-static llvm::GlobalObject &getGlobalObjectInExpr(DiagnosticsEngine &Diags,
-                                                 const AliasAttr *AA,
-                                                 llvm::Constant *C) {
-  if (auto *GO = dyn_cast<llvm::GlobalObject>(C))
-    return *GO;
-
-  auto *GA = dyn_cast<llvm::GlobalAlias>(C);
-  if (GA) {
-    if (GA->mayBeOverridden()) {
-      Diags.Report(AA->getLocation(), diag::warn_alias_to_weak_alias)
-          << GA->getAliasee()->getName() << GA->getName();
-    }
-
-    return *GA->getAliasee();
-  }
-
-  auto *CE = cast<llvm::ConstantExpr>(C);
-  assert(CE->getOpcode() == llvm::Instruction::BitCast ||
-         CE->getOpcode() == llvm::Instruction::GetElementPtr ||
-         CE->getOpcode() == llvm::Instruction::AddrSpaceCast);
-  return *cast<llvm::GlobalObject>(CE->getOperand(0));
-}
-
 void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
   const auto *D = cast<ValueDecl>(GD.getDecl());
   const AliasAttr *AA = D->getAttr<AliasAttr>();
@@ -2274,8 +2366,7 @@
   // Create the new alias itself, but don't set a name yet.
   auto *GA = llvm::GlobalAlias::create(
       cast<llvm::PointerType>(Aliasee->getType())->getElementType(), 0,
-      llvm::Function::ExternalLinkage, "",
-      &getGlobalObjectInExpr(Diags, AA, Aliasee));
+      llvm::Function::ExternalLinkage, "", Aliasee, &getModule());
 
   if (Entry) {
     if (GA->getAliasee() == Entry) {
@@ -2659,72 +2750,67 @@
   return llvm::ConstantDataArray::get(VMContext, Elements);
 }
 
+static llvm::GlobalVariable *
+GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT,
+                      CodeGenModule &CGM, StringRef GlobalName,
+                      unsigned Alignment) {
+  // OpenCL v1.2 s6.5.3: a string literal is in the constant address space.
+  unsigned AddrSpace = 0;
+  if (CGM.getLangOpts().OpenCL)
+    AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_constant);
+
+  // Create a global variable for this string
+  auto *GV = new llvm::GlobalVariable(
+      CGM.getModule(), C->getType(), !CGM.getLangOpts().WritableStrings, LT, C,
+      GlobalName, nullptr, llvm::GlobalVariable::NotThreadLocal, AddrSpace);
+  GV->setAlignment(Alignment);
+  GV->setUnnamedAddr(true);
+  return GV;
+}
+
 /// GetAddrOfConstantStringFromLiteral - Return a pointer to a
 /// constant array for the given string literal.
 llvm::Constant *
 CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
-  CharUnits Align = getContext().getAlignOfGlobalVarInChars(S->getType());
+  auto Alignment =
+      getContext().getAlignOfGlobalVarInChars(S->getType()).getQuantity();
 
   llvm::StringMapEntry<llvm::GlobalVariable *> *Entry = nullptr;
-  llvm::GlobalVariable *GV = nullptr;
   if (!LangOpts.WritableStrings) {
-    llvm::StringMap<llvm::GlobalVariable *> *ConstantStringMap = nullptr;
-    switch (S->getCharByteWidth()) {
-    case 1:
-      ConstantStringMap = &Constant1ByteStringMap;
-      break;
-    case 2:
-      ConstantStringMap = &Constant2ByteStringMap;
-      break;
-    case 4:
-      ConstantStringMap = &Constant4ByteStringMap;
-      break;
-    default:
-      llvm_unreachable("unhandled byte width!");
+    Entry = getConstantStringMapEntry(S->getBytes(), S->getCharByteWidth());
+    if (auto GV = Entry->getValue()) {
+      if (Alignment > GV->getAlignment())
+        GV->setAlignment(Alignment);
+      return GV;
     }
-    Entry = &ConstantStringMap->GetOrCreateValue(S->getBytes());
-    GV = Entry->getValue();
   }
 
-  if (!GV) {
-    SmallString<256> MangledNameBuffer;
-    StringRef GlobalVariableName;
-    llvm::GlobalValue::LinkageTypes LT;
+  SmallString<256> MangledNameBuffer;
+  StringRef GlobalVariableName;
+  llvm::GlobalValue::LinkageTypes LT;
 
-    // Mangle the string literal if the ABI allows for it.  However, we cannot
-    // do this if  we are compiling with ASan or -fwritable-strings because they
-    // rely on strings having normal linkage.
-    if (!LangOpts.WritableStrings && !SanOpts.Address &&
-        getCXXABI().getMangleContext().shouldMangleStringLiteral(S)) {
-      llvm::raw_svector_ostream Out(MangledNameBuffer);
-      getCXXABI().getMangleContext().mangleStringLiteral(S, Out);
-      Out.flush();
+  // Mangle the string literal if the ABI allows for it.  However, we cannot
+  // do this if  we are compiling with ASan or -fwritable-strings because they
+  // rely on strings having normal linkage.
+  if (!LangOpts.WritableStrings && !LangOpts.Sanitize.Address &&
+      getCXXABI().getMangleContext().shouldMangleStringLiteral(S)) {
+    llvm::raw_svector_ostream Out(MangledNameBuffer);
+    getCXXABI().getMangleContext().mangleStringLiteral(S, Out);
+    Out.flush();
 
-      LT = llvm::GlobalValue::LinkOnceODRLinkage;
-      GlobalVariableName = MangledNameBuffer;
-    } else {
-      LT = llvm::GlobalValue::PrivateLinkage;
-      GlobalVariableName = ".str";
-    }
-
-    // OpenCL v1.2 s6.5.3: a string literal is in the constant address space.
-    unsigned AddrSpace = 0;
-    if (getLangOpts().OpenCL)
-      AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_constant);
-
-    llvm::Constant *C = GetConstantArrayFromStringLiteral(S);
-    GV = new llvm::GlobalVariable(
-        getModule(), C->getType(), !LangOpts.WritableStrings, LT, C,
-        GlobalVariableName, /*InsertBefore=*/nullptr,
-        llvm::GlobalVariable::NotThreadLocal, AddrSpace);
-    GV->setUnnamedAddr(true);
-    if (Entry)
-      Entry->setValue(GV);
+    LT = llvm::GlobalValue::LinkOnceODRLinkage;
+    GlobalVariableName = MangledNameBuffer;
+  } else {
+    LT = llvm::GlobalValue::PrivateLinkage;
+    GlobalVariableName = ".str";
   }
 
-  if (Align.getQuantity() > GV->getAlignment())
-    GV->setAlignment(Align.getQuantity());
+  llvm::Constant *C = GetConstantArrayFromStringLiteral(S);
+  auto GV = GenerateStringLiteral(C, LT, *this, GlobalVariableName, Alignment);
+  if (Entry)
+    Entry->setValue(GV);
 
+  reportGlobalToASan(GV, S->getStrTokenLoc(0));
   return GV;
 }
 
@@ -2739,79 +2825,60 @@
 }
 
 
-/// GenerateWritableString -- Creates storage for a string literal.
-static llvm::GlobalVariable *GenerateStringLiteral(StringRef str,
-                                             bool constant,
-                                             CodeGenModule &CGM,
-                                             const char *GlobalName,
-                                             unsigned Alignment) {
-  // Create Constant for this string literal. Don't add a '\0'.
-  llvm::Constant *C =
-      llvm::ConstantDataArray::getString(CGM.getLLVMContext(), str, false);
-
-  // OpenCL v1.2 s6.5.3: a string literal is in the constant address space.
-  unsigned AddrSpace = 0;
-  if (CGM.getLangOpts().OpenCL)
-    AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_constant);
-
-  // Create a global variable for this string
-  auto *GV = new llvm::GlobalVariable(
-      CGM.getModule(), C->getType(), constant,
-      llvm::GlobalValue::PrivateLinkage, C, GlobalName, nullptr,
-      llvm::GlobalVariable::NotThreadLocal, AddrSpace);
-  GV->setAlignment(Alignment);
-  GV->setUnnamedAddr(true);
-  return GV;
-}
-
-/// GetAddrOfConstantString - Returns a pointer to a character array
-/// containing the literal. This contents are exactly that of the
-/// given string, i.e. it will not be null terminated automatically;
-/// see GetAddrOfConstantCString. Note that whether the result is
-/// actually a pointer to an LLVM constant depends on
-/// Feature.WriteableStrings.
-///
-/// The result has pointer to array type.
-llvm::Constant *CodeGenModule::GetAddrOfConstantString(StringRef Str,
-                                                       const char *GlobalName,
-                                                       unsigned Alignment) {
-  // Get the default prefix if a name wasn't specified.
-  if (!GlobalName)
-    GlobalName = ".str";
-
-  if (Alignment == 0)
-    Alignment = getContext().getAlignOfGlobalVarInChars(getContext().CharTy)
-      .getQuantity();
-
-  // Don't share any string literals if strings aren't constant.
-  if (LangOpts.WritableStrings)
-    return GenerateStringLiteral(Str, false, *this, GlobalName, Alignment);
-
-  llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
-    Constant1ByteStringMap.GetOrCreateValue(Str);
-
-  if (llvm::GlobalVariable *GV = Entry.getValue()) {
-    if (Alignment > GV->getAlignment()) {
-      GV->setAlignment(Alignment);
-    }
-    return GV;
+llvm::StringMapEntry<llvm::GlobalVariable *> *CodeGenModule::getConstantStringMapEntry(
+    StringRef Str, int CharByteWidth) {
+  llvm::StringMap<llvm::GlobalVariable *> *ConstantStringMap = nullptr;
+  switch (CharByteWidth) {
+  case 1:
+    ConstantStringMap = &Constant1ByteStringMap;
+    break;
+  case 2:
+    ConstantStringMap = &Constant2ByteStringMap;
+    break;
+  case 4:
+    ConstantStringMap = &Constant4ByteStringMap;
+    break;
+  default:
+    llvm_unreachable("unhandled byte width!");
   }
-
-  // Create a global variable for this.
-  llvm::GlobalVariable *GV = GenerateStringLiteral(Str, true, *this, GlobalName,
-                                                   Alignment);
-  Entry.setValue(GV);
-  return GV;
+  return &ConstantStringMap->GetOrCreateValue(Str);
 }
 
-/// GetAddrOfConstantCString - Returns a pointer to a character
-/// array containing the literal and a terminating '\0'
-/// character. The result has pointer to array type.
+/// GetAddrOfConstantCString - Returns a pointer to a character array containing
+/// the literal and a terminating '\0' character.
+/// The result has pointer to array type.
 llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &Str,
                                                         const char *GlobalName,
                                                         unsigned Alignment) {
   StringRef StrWithNull(Str.c_str(), Str.size() + 1);
-  return GetAddrOfConstantString(StrWithNull, GlobalName, Alignment);
+  if (Alignment == 0) {
+    Alignment = getContext()
+                    .getAlignOfGlobalVarInChars(getContext().CharTy)
+                    .getQuantity();
+  }
+
+  // Don't share any string literals if strings aren't constant.
+  llvm::StringMapEntry<llvm::GlobalVariable *> *Entry = nullptr;
+  if (!LangOpts.WritableStrings) {
+    Entry = getConstantStringMapEntry(StrWithNull, 1);
+    if (auto GV = Entry->getValue()) {
+      if (Alignment > GV->getAlignment())
+        GV->setAlignment(Alignment);
+      return GV;
+    }
+  }
+
+  llvm::Constant *C =
+      llvm::ConstantDataArray::getString(getLLVMContext(), StrWithNull, false);
+  // Get the default prefix if a name wasn't specified.
+  if (!GlobalName)
+    GlobalName = ".str";
+  // Create a global variable for this.
+  auto GV = GenerateStringLiteral(C, llvm::GlobalValue::PrivateLinkage, *this,
+                                  GlobalName, Alignment);
+  if (Entry)
+    Entry->setValue(GV);
+  return GV;
 }
 
 llvm::Constant *CodeGenModule::GetAddrOfGlobalTemporary(
@@ -3200,11 +3267,19 @@
     IdentifierInfo *Name = I->first;
     llvm::GlobalValue *Val = I->second;
     if (Val && !getModule().getNamedValue(Name->getName()))
-      addUsedGlobal(llvm::GlobalAlias::create(Name->getName(),
-                                              cast<llvm::GlobalObject>(Val)));
+      addUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val));
   }
 }
 
+bool CodeGenModule::lookupRepresentativeDecl(StringRef MangledName,
+                                             GlobalDecl &Result) const {
+  auto Res = Manglings.find(MangledName);
+  if (Res == Manglings.end())
+    return false;
+  Result = Res->getValue();
+  return true;
+}
+
 /// Emits metadata nodes associating all the global values in the
 /// current module with the Decls they came from.  This is useful for
 /// projects using IR gen as a subroutine.
@@ -3216,11 +3291,9 @@
   llvm::NamedMDNode *GlobalMetadata = nullptr;
 
   // StaticLocalDeclMap
-  for (llvm::DenseMap<GlobalDecl,StringRef>::iterator
-         I = MangledDeclNames.begin(), E = MangledDeclNames.end();
-       I != E; ++I) {
-    llvm::GlobalValue *Addr = getModule().getNamedValue(I->second);
-    EmitGlobalDeclMetadata(*this, GlobalMetadata, I->first, Addr);
+  for (auto &I : MangledDeclNames) {
+    llvm::GlobalValue *Addr = getModule().getNamedValue(I.second);
+    EmitGlobalDeclMetadata(*this, GlobalMetadata, I.first, Addr);
   }
 }
 
@@ -3236,11 +3309,9 @@
 
   llvm::NamedMDNode *GlobalMetadata = nullptr;
 
-  for (llvm::DenseMap<const Decl*, llvm::Value*>::iterator
-         I = LocalDeclMap.begin(), E = LocalDeclMap.end(); I != E; ++I) {
-    const Decl *D = I->first;
-    llvm::Value *Addr = I->second;
-
+  for (auto &I : LocalDeclMap) {
+    const Decl *D = I.first;
+    llvm::Value *Addr = I.second;
     if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Addr)) {
       llvm::Value *DAddr = GetPointerConstant(getLLVMContext(), D);
       Alloca->setMetadata(DeclPtrKind, llvm::MDNode::get(Context, DAddr));
@@ -3263,6 +3334,14 @@
   IdentMetadata->addOperand(llvm::MDNode::get(Ctx, IdentNode));
 }
 
+void CodeGenModule::EmitTargetMetadata() {
+  for (auto &I : MangledDeclNames) {
+    const Decl *D = I.first.getDecl()->getMostRecentDecl();
+    llvm::GlobalValue *GV = GetGlobalValue(I.second);
+    getTargetCodeGenInfo().emitTargetMD(D, GV, *this);
+  }
+}
+
 void CodeGenModule::EmitCoverageFile() {
   if (!getCodeGenOpts().CoverageFile.empty()) {
     if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) {
@@ -3306,3 +3385,19 @@
 
   return llvm::ConstantStruct::getAnon(Fields);
 }
+
+llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
+                                                       bool ForEH) {
+  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
+  // FIXME: should we even be calling this method if RTTI is disabled
+  // and it's not for EH?
+  if (!ForEH && !getLangOpts().RTTI)
+    return llvm::Constant::getNullValue(Int8PtrTy);
+  
+  if (ForEH && Ty->isObjCObjectPointerType() &&
+      LangOpts.ObjCRuntime.isGNUFamily())
+    return ObjCRuntime->GetEHType(Ty);
+
+  return getCXXABI().getAddrOfRTTIDescriptor(Ty);
+}
+
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index c54f6de..649b0e5 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -16,6 +16,7 @@
 
 #include "CGVTables.h"
 #include "CodeGenTypes.h"
+#include "SanitizerBlacklist.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
@@ -31,7 +32,6 @@
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ValueHandle.h"
-#include "llvm/Transforms/Utils/SpecialCaseList.h"
 
 namespace llvm {
 class Module;
@@ -71,7 +71,6 @@
 class DiagnosticsEngine;
 class AnnotateAttr;
 class CXXDestructorDecl;
-class MangleBuffer;
 class Module;
 
 namespace CodeGen {
@@ -219,12 +218,36 @@
 };
 
 /// This class records statistics on instrumentation based profiling.
-struct InstrProfStats {
-  InstrProfStats() : Visited(0), Missing(0), Mismatched(0) {}
-  bool isOutOfDate() { return Missing || Mismatched; }
+class InstrProfStats {
+  uint32_t VisitedInMainFile;
+  uint32_t MissingInMainFile;
   uint32_t Visited;
   uint32_t Missing;
   uint32_t Mismatched;
+
+public:
+  InstrProfStats()
+      : VisitedInMainFile(0), MissingInMainFile(0), Visited(0), Missing(0),
+        Mismatched(0) {}
+  /// Record that we've visited a function and whether or not that function was
+  /// in the main source file.
+  void addVisited(bool MainFile) {
+    if (MainFile)
+      ++VisitedInMainFile;
+    ++Visited;
+  }
+  /// Record that a function we've visited has no profile data.
+  void addMissing(bool MainFile) {
+    if (MainFile)
+      ++MissingInMainFile;
+    ++Missing;
+  }
+  /// Record that a function we've visited has mismatched profile data.
+  void addMismatched(bool MainFile) { ++Mismatched; }
+  /// Whether or not the stats we've gathered indicate any potential problems.
+  bool hasDiagnostics() { return Missing || Mismatched; }
+  /// Report potential problems we've found to \c Diags.
+  void reportDiagnostics(DiagnosticsEngine &Diags, StringRef MainFile);
 };
 
 /// This class organizes the cross-function state that is used while generating
@@ -288,7 +311,7 @@
   /// for emission and therefore should only be output if they are actually
   /// used. If a decl is in this, then it is known to have not been referenced
   /// yet.
-  llvm::StringMap<GlobalDecl> DeferredDecls;
+  std::map<StringRef, GlobalDecl> DeferredDecls;
 
   /// This is a list of deferred decls which we have seen that *are* actually
   /// referenced. These get code generated when the module is done.
@@ -326,10 +349,10 @@
   /// emitted when the translation unit is complete.
   CtorList GlobalDtors;
 
-  /// A map of canonical GlobalDecls to their mangled names.
-  llvm::DenseMap<GlobalDecl, StringRef> MangledDeclNames;
-  llvm::BumpPtrAllocator MangledNamesAllocator;
-  
+  /// An ordered map of canonical GlobalDecls to their mangled names.
+  llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames;
+  llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings;
+
   /// Global annotations.
   std::vector<llvm::Constant*> Annotations;
 
@@ -450,9 +473,7 @@
 
   GlobalDecl initializedGlobalDecl;
 
-  std::unique_ptr<llvm::SpecialCaseList> SanitizerBlacklist;
-
-  const SanitizerOptions &SanOpts;
+  SanitizerBlacklist SanitizerBL;
 
   /// @}
 public:
@@ -523,6 +544,9 @@
     StaticLocalDeclGuardMap[D] = C;
   }
 
+  bool lookupRepresentativeDecl(StringRef MangledName,
+                                GlobalDecl &Result) const;
+
   llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) {
     return AtomicSetterHelperFnMap[Ty];
   }
@@ -721,12 +745,6 @@
   /// The type of a generic block literal.
   llvm::Type *getGenericBlockLiteralType();
 
-  /// \brief Gets or a creats a Microsoft TypeDescriptor.
-  llvm::Constant *getMSTypeDescriptor(QualType Ty);
-  /// \brief Gets or a creats a Microsoft CompleteObjectLocator.
-  llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
-                                                   const VPtrInfo *Info);
-
   /// Gets the address of a block which requires no captures.
   llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
   
@@ -747,28 +765,14 @@
   /// Return a pointer to a constant array for the given ObjCEncodeExpr node.
   llvm::Constant *GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *);
 
-  /// Returns a pointer to a character array containing the literal. This
-  /// contents are exactly that of the given string, i.e. it will not be null
-  /// terminated automatically; see GetAddrOfConstantCString. Note that whether
-  /// the result is actually a pointer to an LLVM constant depends on
-  /// Feature.WriteableStrings.
-  ///
-  /// The result has pointer to array type.
-  ///
-  /// \param GlobalName If provided, the name to use for the global
-  /// (if one is created).
-  llvm::Constant *GetAddrOfConstantString(StringRef Str,
-                                          const char *GlobalName=nullptr,
-                                          unsigned Alignment=0);
-
   /// Returns a pointer to a character array containing the literal and a
   /// terminating '\0' character. The result has pointer to array type.
   ///
   /// \param GlobalName If provided, the name to use for the global (if one is
   /// created).
   llvm::Constant *GetAddrOfConstantCString(const std::string &str,
-                                           const char *GlobalName=nullptr,
-                                           unsigned Alignment=0);
+                                           const char *GlobalName = nullptr,
+                                           unsigned Alignment = 0);
 
   /// Returns a pointer to a constant global variable for the given file-scope
   /// compound literal expression.
@@ -937,8 +941,7 @@
                               bool AttrOnCallSite);
 
   StringRef getMangledName(GlobalDecl GD);
-  void getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
-                           const BlockDecl *BD);
+  StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
 
   void EmitTentativeDefinition(const VarDecl *D);
 
@@ -962,9 +965,6 @@
     F->setLinkage(getFunctionLinkage(GD));
   }
 
-  /// \brief Returns the appropriate linkage for the TypeInfo struct for a type.
-  llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty);
-
   /// Return the appropriate linkage for the vtable, VTT, and type information
   /// of the given class.
   llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD);
@@ -1008,11 +1008,12 @@
   /// annotations are emitted during finalization of the LLVM code.
   void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
 
-  const llvm::SpecialCaseList &getSanitizerBlacklist() const {
-    return *SanitizerBlacklist;
+  const SanitizerBlacklist &getSanitizerBlacklist() const {
+    return SanitizerBL;
   }
 
-  const SanitizerOptions &getSanOpts() const { return SanOpts; }
+  void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
+                          bool IsDynInit = false);
 
   void addDeferredVTable(const CXXRecordDecl *RD) {
     DeferredVTables.push_back(RD);
@@ -1034,6 +1035,9 @@
                                         llvm::PointerType *PTy,
                                         const VarDecl *D);
 
+  llvm::StringMapEntry<llvm::GlobalVariable *> *
+  getConstantStringMapEntry(StringRef Str, int CharByteWidth);
+
   /// Set attributes which are common to any form of a global definition (alias,
   /// Objective-C method, function, global variable).
   ///
@@ -1129,6 +1133,9 @@
   /// \brief Emit the Clang version as llvm.ident metadata.
   void EmitVersionIdentMetadata();
 
+  /// Emits target specific Metadata for global declarations.
+  void EmitTargetMetadata();
+
   /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and
   /// .gcda files in a way that persists in .bc files.
   void EmitCoverageFile();
diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp
index 22534b8..b233e3c 100644
--- a/lib/CodeGen/CodeGenPGO.cpp
+++ b/lib/CodeGen/CodeGenPGO.cpp
@@ -837,7 +837,8 @@
     emitCounterVariables();
   }
   if (PGOReader) {
-    loadRegionCounts(PGOReader);
+    SourceManager &SM = CGM.getContext().getSourceManager();
+    loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
     computeRegionCounts(D);
     applyFunctionAttributes(PGOReader, Fn);
   }
@@ -912,16 +913,17 @@
   Builder.CreateStore(Count, Addr);
 }
 
-void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader) {
-  CGM.getPGOStats().Visited++;
+void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
+                                  bool IsInMainFile) {
+  CGM.getPGOStats().addVisited(IsInMainFile);
   RegionCounts.reset(new std::vector<uint64_t>);
   uint64_t Hash;
   if (PGOReader->getFunctionCounts(getFuncName(), Hash, *RegionCounts)) {
-    CGM.getPGOStats().Missing++;
+    CGM.getPGOStats().addMissing(IsInMainFile);
     RegionCounts.reset();
   } else if (Hash != FunctionHash ||
              RegionCounts->size() != NumRegionCounters) {
-    CGM.getPGOStats().Mismatched++;
+    CGM.getPGOStats().addMismatched(IsInMainFile);
     RegionCounts.reset();
   }
 }
diff --git a/lib/CodeGen/CodeGenPGO.h b/lib/CodeGen/CodeGenPGO.h
index c434808..2f4aa66 100644
--- a/lib/CodeGen/CodeGenPGO.h
+++ b/lib/CodeGen/CodeGenPGO.h
@@ -118,7 +118,8 @@
   void computeRegionCounts(const Decl *D);
   void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
                                llvm::Function *Fn);
-  void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader);
+  void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
+                        bool IsInMainFile);
   void emitCounterVariables();
   llvm::GlobalVariable *buildDataVar();
 
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 59e3089..fe155b5 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -104,7 +104,7 @@
   
 private:
   /// TypeCache - This map keeps cache of llvm::Types
-  /// and maps llvm::Types to corresponding clang::Type.
+  /// and maps clang::Type to corresponding llvm::Type.
   llvm::DenseMap<const Type *, llvm::Type *> TypeCache;
 
 public:
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index f5d2372..baf0927 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -25,6 +25,7 @@
 #include "CodeGenModule.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/Type.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Value.h"
@@ -108,6 +109,30 @@
   llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, llvm::Value *ptr,
                                       QualType type) override;
 
+  void EmitFundamentalRTTIDescriptor(QualType Type);
+  void EmitFundamentalRTTIDescriptors();
+  llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
+
+  bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
+  void EmitBadTypeidCall(CodeGenFunction &CGF) override;
+  llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
+                          llvm::Value *ThisPtr,
+                          llvm::Type *StdTypeInfoPtrTy) override;
+
+  bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                          QualType SrcRecordTy) override;
+
+  llvm::Value *EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
+                                   QualType SrcRecordTy, QualType DestTy,
+                                   QualType DestRecordTy,
+                                   llvm::BasicBlock *CastEnd) override;
+
+  llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF, llvm::Value *Value,
+                                     QualType SrcRecordTy,
+                                     QualType DestTy) override;
+
+  bool EmitBadCastCall(CodeGenFunction &CGF) override;
+
   llvm::Value *
     GetVirtualBaseClassOffset(CodeGenFunction &CGF, llvm::Value *This,
                               const CXXRecordDecl *ClassDecl,
@@ -174,7 +199,8 @@
 
   void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
 
-  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) override {
+  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD,
+                       bool ReturnAdjustment) override {
     // Allow inlining of thunks by emitting them with available_externally
     // linkage together with vtables when needed.
     if (ForVTable)
@@ -210,12 +236,43 @@
   llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD,
                                                 llvm::GlobalVariable *Var);
   void EmitThreadLocalInitFuncs(
-      llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+      ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
       llvm::Function *InitFunc) override;
   LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,
                                       QualType LValType) override;
 
   bool NeedsVTTParameter(GlobalDecl GD) override;
+
+  /**************************** RTTI Uniqueness ******************************/
+
+protected:
+  /// Returns true if the ABI requires RTTI type_info objects to be unique
+  /// across a program.
+  virtual bool shouldRTTIBeUnique() const { return true; }
+
+public:
+  /// What sort of unique-RTTI behavior should we use?
+  enum RTTIUniquenessKind {
+    /// We are guaranteeing, or need to guarantee, that the RTTI string
+    /// is unique.
+    RUK_Unique,
+
+    /// We are not guaranteeing uniqueness for the RTTI string, so we
+    /// can demote to hidden visibility but must use string comparisons.
+    RUK_NonUniqueHidden,
+
+    /// We are not guaranteeing uniqueness for the RTTI string, so we
+    /// have to use string comparisons, but we also have to emit it with
+    /// non-hidden visibility.
+    RUK_NonUniqueVisible
+  };
+
+  /// Return the required visibility status for the given type and linkage in
+  /// the current ABI.
+  RTTIUniquenessKind
+  classifyRTTIUniqueness(QualType CanTy,
+                         llvm::GlobalValue::LinkageTypes Linkage) const;
+  friend class ItaniumRTTIBuilder;
 };
 
 class ARMCXXABI : public ItaniumCXXABI {
@@ -248,7 +305,7 @@
   iOS64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {}
 
   // ARM64 libraries are prepared for non-unique RTTI.
-  bool shouldRTTIBeUnique() override { return false; }
+  bool shouldRTTIBeUnique() const override { return false; }
 };
 }
 
@@ -799,6 +856,194 @@
   return CGF.Builder.CreateInBoundsGEP(ptr, offset);
 }
 
+static llvm::Constant *getItaniumDynamicCastFn(CodeGenFunction &CGF) {
+  // void *__dynamic_cast(const void *sub,
+  //                      const abi::__class_type_info *src,
+  //                      const abi::__class_type_info *dst,
+  //                      std::ptrdiff_t src2dst_offset);
+  
+  llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
+  llvm::Type *PtrDiffTy = 
+    CGF.ConvertType(CGF.getContext().getPointerDiffType());
+
+  llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
+
+  llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
+
+  // Mark the function as nounwind readonly.
+  llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
+                                            llvm::Attribute::ReadOnly };
+  llvm::AttributeSet Attrs = llvm::AttributeSet::get(
+      CGF.getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs);
+}
+
+static llvm::Constant *getBadCastFn(CodeGenFunction &CGF) {
+  // void __cxa_bad_cast();
+  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast");
+}
+
+/// \brief Compute the src2dst_offset hint as described in the
+/// Itanium C++ ABI [2.9.7]
+static CharUnits computeOffsetHint(ASTContext &Context,
+                                   const CXXRecordDecl *Src,
+                                   const CXXRecordDecl *Dst) {
+  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                     /*DetectVirtual=*/false);
+
+  // If Dst is not derived from Src we can skip the whole computation below and
+  // return that Src is not a public base of Dst.  Record all inheritance paths.
+  if (!Dst->isDerivedFrom(Src, Paths))
+    return CharUnits::fromQuantity(-2ULL);
+
+  unsigned NumPublicPaths = 0;
+  CharUnits Offset;
+
+  // Now walk all possible inheritance paths.
+  for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end(); I != E;
+       ++I) {
+    if (I->Access != AS_public) // Ignore non-public inheritance.
+      continue;
+
+    ++NumPublicPaths;
+
+    for (CXXBasePath::iterator J = I->begin(), JE = I->end(); J != JE; ++J) {
+      // If the path contains a virtual base class we can't give any hint.
+      // -1: no hint.
+      if (J->Base->isVirtual())
+        return CharUnits::fromQuantity(-1ULL);
+
+      if (NumPublicPaths > 1) // Won't use offsets, skip computation.
+        continue;
+
+      // Accumulate the base class offsets.
+      const ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
+      Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
+    }
+  }
+
+  // -2: Src is not a public base of Dst.
+  if (NumPublicPaths == 0)
+    return CharUnits::fromQuantity(-2ULL);
+
+  // -3: Src is a multiple public base type but never a virtual base type.
+  if (NumPublicPaths > 1)
+    return CharUnits::fromQuantity(-3ULL);
+
+  // Otherwise, the Src type is a unique public nonvirtual base type of Dst.
+  // Return the offset of Src from the origin of Dst.
+  return Offset;
+}
+
+static llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) {
+  // void __cxa_bad_typeid();
+  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
+}
+
+bool ItaniumCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
+                                              QualType SrcRecordTy) {
+  return IsDeref;
+}
+
+void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
+  llvm::Value *Fn = getBadTypeidFn(CGF);
+  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
+  CGF.Builder.CreateUnreachable();
+}
+
+llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
+                                       QualType SrcRecordTy,
+                                       llvm::Value *ThisPtr,
+                                       llvm::Type *StdTypeInfoPtrTy) {
+  llvm::Value *Value =
+      CGF.GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo());
+
+  // Load the type info.
+  Value = CGF.Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
+  return CGF.Builder.CreateLoad(Value);
+}
+
+bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                                       QualType SrcRecordTy) {
+  return SrcIsPtr;
+}
+
+llvm::Value *ItaniumCXXABI::EmitDynamicCastCall(
+    CodeGenFunction &CGF, llvm::Value *Value, QualType SrcRecordTy,
+    QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
+  llvm::Type *PtrDiffLTy =
+      CGF.ConvertType(CGF.getContext().getPointerDiffType());
+  llvm::Type *DestLTy = CGF.ConvertType(DestTy);
+
+  llvm::Value *SrcRTTI =
+      CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
+  llvm::Value *DestRTTI =
+      CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
+
+  // Compute the offset hint.
+  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
+  const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();
+  llvm::Value *OffsetHint = llvm::ConstantInt::get(
+      PtrDiffLTy,
+      computeOffsetHint(CGF.getContext(), SrcDecl, DestDecl).getQuantity());
+
+  // Emit the call to __dynamic_cast.
+  Value = CGF.EmitCastToVoidPtr(Value);
+
+  llvm::Value *args[] = {Value, SrcRTTI, DestRTTI, OffsetHint};
+  Value = CGF.EmitNounwindRuntimeCall(getItaniumDynamicCastFn(CGF), args);
+  Value = CGF.Builder.CreateBitCast(Value, DestLTy);
+
+  /// C++ [expr.dynamic.cast]p9:
+  ///   A failed cast to reference type throws std::bad_cast
+  if (DestTy->isReferenceType()) {
+    llvm::BasicBlock *BadCastBlock =
+        CGF.createBasicBlock("dynamic_cast.bad_cast");
+
+    llvm::Value *IsNull = CGF.Builder.CreateIsNull(Value);
+    CGF.Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
+
+    CGF.EmitBlock(BadCastBlock);
+    EmitBadCastCall(CGF);
+  }
+
+  return Value;
+}
+
+llvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF,
+                                                  llvm::Value *Value,
+                                                  QualType SrcRecordTy,
+                                                  QualType DestTy) {
+  llvm::Type *PtrDiffLTy =
+      CGF.ConvertType(CGF.getContext().getPointerDiffType());
+  llvm::Type *DestLTy = CGF.ConvertType(DestTy);
+
+  // Get the vtable pointer.
+  llvm::Value *VTable = CGF.GetVTablePtr(Value, PtrDiffLTy->getPointerTo());
+
+  // Get the offset-to-top from the vtable.
+  llvm::Value *OffsetToTop =
+      CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
+  OffsetToTop = CGF.Builder.CreateLoad(OffsetToTop, "offset.to.top");
+
+  // Finally, add the offset to the pointer.
+  Value = CGF.EmitCastToVoidPtr(Value);
+  Value = CGF.Builder.CreateInBoundsGEP(Value, OffsetToTop);
+
+  return CGF.Builder.CreateBitCast(Value, DestLTy);
+}
+
+bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
+  llvm::Value *Fn = getBadCastFn(CGF);
+  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
+  CGF.Builder.CreateUnreachable();
+  return true;
+}
+
 llvm::Value *
 ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
                                          llvm::Value *This,
@@ -972,11 +1217,13 @@
   ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
   const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);
   llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
+  llvm::Constant *RTTI =
+      CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
 
   // Create and set the initializer.
   llvm::Constant *Init = CGVT.CreateVTableInitializer(
       RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(),
-      VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks());
+      VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks(), RTTI);
   VTable->setInitializer(Init);
 
   // Set the correct linkage.
@@ -994,7 +1241,7 @@
       isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
       cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&
       DC->getParent()->isTranslationUnit())
-    CGM.EmitFundamentalRTTIDescriptors();
+    EmitFundamentalRTTIDescriptors();
 }
 
 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
@@ -1069,6 +1316,12 @@
   VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
       Name, ArrayType, llvm::GlobalValue::ExternalLinkage);
   VTable->setUnnamedAddr(true);
+
+  if (RD->hasAttr<DLLImportAttr>())
+    VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+  else if (RD->hasAttr<DLLExportAttr>())
+    VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+
   return VTable;
 }
 
@@ -1566,13 +1819,23 @@
 }
 
 /// Get the appropriate linkage for the wrapper function. This is essentially
-/// the weak form of the variable's linkage; every translation unit which wneeds
+/// the weak form of the variable's linkage; every translation unit which needs
 /// the wrapper emits a copy, and we want the linker to merge them.
-static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(
-    llvm::GlobalValue::LinkageTypes VarLinkage) {
+static llvm::GlobalValue::LinkageTypes
+getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {
+  llvm::GlobalValue::LinkageTypes VarLinkage =
+      CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false);
+
   // For internal linkage variables, we don't need an external or weak wrapper.
   if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
     return VarLinkage;
+
+  // All accesses to the thread_local variable go through the thread wrapper.
+  // However, this means that we cannot allow the thread wrapper to get inlined
+  // into any functions.
+  if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+      CGM.getTarget().getTriple().isMacOSX())
+    return llvm::GlobalValue::WeakAnyLinkage;
   return llvm::GlobalValue::WeakODRLinkage;
 }
 
@@ -1595,10 +1858,9 @@
     RetTy = RetTy->getPointerElementType();
 
   llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false);
-  llvm::Function *Wrapper = llvm::Function::Create(
-      FnTy, getThreadLocalWrapperLinkage(
-                CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false)),
-      WrapperName.str(), &CGM.getModule());
+  llvm::Function *Wrapper =
+      llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM),
+                             WrapperName.str(), &CGM.getModule());
   // Always resolve references to the wrapper at link time.
   if (!Wrapper->hasLocalLinkage())
     Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
@@ -1606,7 +1868,7 @@
 }
 
 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
-    llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+    ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
     llvm::Function *InitFunc) {
   for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
     const VarDecl *VD = Decls[I].first;
@@ -1717,3 +1979,996 @@
   
   return false;
 }
+
+namespace {
+class ItaniumRTTIBuilder {
+  CodeGenModule &CGM;  // Per-module state.
+  llvm::LLVMContext &VMContext;
+  const ItaniumCXXABI &CXXABI;  // Per-module state.
+
+  /// Fields - The fields of the RTTI descriptor currently being built.
+  SmallVector<llvm::Constant *, 16> Fields;
+
+  /// GetAddrOfTypeName - Returns the mangled type name of the given type.
+  llvm::GlobalVariable *
+  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
+
+  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI
+  /// descriptor of the given type.
+  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
+
+  /// BuildVTablePointer - Build the vtable pointer for the given type.
+  void BuildVTablePointer(const Type *Ty);
+
+  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
+  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
+  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
+
+  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
+  /// classes with bases that do not satisfy the abi::__si_class_type_info
+  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
+  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
+
+  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
+  /// for pointer types.
+  void BuildPointerTypeInfo(QualType PointeeTy);
+
+  /// BuildObjCObjectTypeInfo - Build the appropriate kind of
+  /// type_info for an object type.
+  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
+
+  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
+  /// struct, used for member pointer types.
+  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
+
+public:
+  ItaniumRTTIBuilder(const ItaniumCXXABI &ABI)
+      : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {}
+
+  // Pointer type info flags.
+  enum {
+    /// PTI_Const - Type has const qualifier.
+    PTI_Const = 0x1,
+
+    /// PTI_Volatile - Type has volatile qualifier.
+    PTI_Volatile = 0x2,
+
+    /// PTI_Restrict - Type has restrict qualifier.
+    PTI_Restrict = 0x4,
+
+    /// PTI_Incomplete - Type is incomplete.
+    PTI_Incomplete = 0x8,
+
+    /// PTI_ContainingClassIncomplete - Containing class is incomplete.
+    /// (in pointer to member).
+    PTI_ContainingClassIncomplete = 0x10
+  };
+
+  // VMI type info flags.
+  enum {
+    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
+    VMI_NonDiamondRepeat = 0x1,
+
+    /// VMI_DiamondShaped - Class is diamond shaped.
+    VMI_DiamondShaped = 0x2
+  };
+
+  // Base class type info flags.
+  enum {
+    /// BCTI_Virtual - Base class is virtual.
+    BCTI_Virtual = 0x1,
+
+    /// BCTI_Public - Base class is public.
+    BCTI_Public = 0x2
+  };
+
+  /// BuildTypeInfo - Build the RTTI type info struct for the given type.
+  ///
+  /// \param Force - true to force the creation of this RTTI value
+  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
+};
+}
+
+llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
+    QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  // We know that the mangled name of the type starts at index 4 of the
+  // mangled name of the typename, so we can just index into it in order to
+  // get the mangled name of the type.
+  llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
+                                                            Name.substr(4));
+
+  llvm::GlobalVariable *GV =
+    CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);
+
+  GV->setInitializer(Init);
+
+  return GV;
+}
+
+llvm::Constant *
+ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
+  // Mangle the RTTI name.
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  // Look for an existing global.
+  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
+
+  if (!GV) {
+    // Create a new global variable.
+    GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
+                                  /*Constant=*/true,
+                                  llvm::GlobalValue::ExternalLinkage, nullptr,
+                                  Name);
+  }
+
+  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+}
+
+/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
+/// info for that type is defined in the standard library.
+static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
+  // Itanium C++ ABI 2.9.2:
+  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
+  //   the run-time support library. Specifically, the run-time support
+  //   library should contain type_info objects for the types X, X* and
+  //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
+  //   unsigned char, signed char, short, unsigned short, int, unsigned int,
+  //   long, unsigned long, long long, unsigned long long, float, double,
+  //   long double, char16_t, char32_t, and the IEEE 754r decimal and
+  //   half-precision floating point types.
+  switch (Ty->getKind()) {
+    case BuiltinType::Void:
+    case BuiltinType::NullPtr:
+    case BuiltinType::Bool:
+    case BuiltinType::WChar_S:
+    case BuiltinType::WChar_U:
+    case BuiltinType::Char_U:
+    case BuiltinType::Char_S:
+    case BuiltinType::UChar:
+    case BuiltinType::SChar:
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+    case BuiltinType::Long:
+    case BuiltinType::ULong:
+    case BuiltinType::LongLong:
+    case BuiltinType::ULongLong:
+    case BuiltinType::Half:
+    case BuiltinType::Float:
+    case BuiltinType::Double:
+    case BuiltinType::LongDouble:
+    case BuiltinType::Char16:
+    case BuiltinType::Char32:
+    case BuiltinType::Int128:
+    case BuiltinType::UInt128:
+    case BuiltinType::OCLImage1d:
+    case BuiltinType::OCLImage1dArray:
+    case BuiltinType::OCLImage1dBuffer:
+    case BuiltinType::OCLImage2d:
+    case BuiltinType::OCLImage2dArray:
+    case BuiltinType::OCLImage3d:
+    case BuiltinType::OCLSampler:
+    case BuiltinType::OCLEvent:
+      return true;
+
+    case BuiltinType::Dependent:
+#define BUILTIN_TYPE(Id, SingletonId)
+#define PLACEHOLDER_TYPE(Id, SingletonId) \
+    case BuiltinType::Id:
+#include "clang/AST/BuiltinTypes.def"
+      llvm_unreachable("asking for RRTI for a placeholder type!");
+
+    case BuiltinType::ObjCId:
+    case BuiltinType::ObjCClass:
+    case BuiltinType::ObjCSel:
+      llvm_unreachable("FIXME: Objective-C types are unsupported!");
+  }
+
+  llvm_unreachable("Invalid BuiltinType Kind!");
+}
+
+static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
+  QualType PointeeTy = PointerTy->getPointeeType();
+  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
+  if (!BuiltinTy)
+    return false;
+
+  // Check the qualifiers.
+  Qualifiers Quals = PointeeTy.getQualifiers();
+  Quals.removeConst();
+
+  if (!Quals.empty())
+    return false;
+
+  return TypeInfoIsInStandardLibrary(BuiltinTy);
+}
+
+/// IsStandardLibraryRTTIDescriptor - Returns whether the type
+/// information for the given type exists in the standard library.
+static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
+  // Type info for builtin types is defined in the standard library.
+  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
+    return TypeInfoIsInStandardLibrary(BuiltinTy);
+
+  // Type info for some pointer types to builtin types is defined in the
+  // standard library.
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+    return TypeInfoIsInStandardLibrary(PointerTy);
+
+  return false;
+}
+
+/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
+/// the given type exists somewhere else, and that we should not emit the type
+/// information in this translation unit.  Assumes that it is not a
+/// standard-library type.
+static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
+                                            QualType Ty) {
+  ASTContext &Context = CGM.getContext();
+
+  // If RTTI is disabled, assume it might be disabled in the
+  // translation unit that defines any potential key function, too.
+  if (!Context.getLangOpts().RTTI) return false;
+
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+    if (!RD->hasDefinition())
+      return false;
+
+    if (!RD->isDynamicClass())
+      return false;
+
+    // FIXME: this may need to be reconsidered if the key function
+    // changes.
+    return CGM.getVTables().isVTableExternal(RD);
+  }
+
+  return false;
+}
+
+/// IsIncompleteClassType - Returns whether the given record type is incomplete.
+static bool IsIncompleteClassType(const RecordType *RecordTy) {
+  return !RecordTy->getDecl()->isCompleteDefinition();
+}
+
+/// ContainsIncompleteClassType - Returns whether the given type contains an
+/// incomplete class type. This is true if
+///
+///   * The given type is an incomplete class type.
+///   * The given type is a pointer type whose pointee type contains an
+///     incomplete class type.
+///   * The given type is a member pointer type whose class is an incomplete
+///     class type.
+///   * The given type is a member pointer type whoise pointee type contains an
+///     incomplete class type.
+/// is an indirect or direct pointer to an incomplete class type.
+static bool ContainsIncompleteClassType(QualType Ty) {
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    if (IsIncompleteClassType(RecordTy))
+      return true;
+  }
+
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+    return ContainsIncompleteClassType(PointerTy->getPointeeType());
+
+  if (const MemberPointerType *MemberPointerTy =
+      dyn_cast<MemberPointerType>(Ty)) {
+    // Check if the class type is incomplete.
+    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
+    if (IsIncompleteClassType(ClassType))
+      return true;
+
+    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
+  }
+
+  return false;
+}
+
+// CanUseSingleInheritance - Return whether the given record decl has a "single,
+// public, non-virtual base at offset zero (i.e. the derived class is dynamic
+// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
+static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
+  // Check the number of bases.
+  if (RD->getNumBases() != 1)
+    return false;
+
+  // Get the base.
+  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
+
+  // Check that the base is not virtual.
+  if (Base->isVirtual())
+    return false;
+
+  // Check that the base is public.
+  if (Base->getAccessSpecifier() != AS_public)
+    return false;
+
+  // Check that the class is dynamic iff the base is.
+  const CXXRecordDecl *BaseDecl =
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+  if (!BaseDecl->isEmpty() &&
+      BaseDecl->isDynamicClass() != RD->isDynamicClass())
+    return false;
+
+  return true;
+}
+
+void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
+  // abi::__class_type_info.
+  static const char * const ClassTypeInfo =
+    "_ZTVN10__cxxabiv117__class_type_infoE";
+  // abi::__si_class_type_info.
+  static const char * const SIClassTypeInfo =
+    "_ZTVN10__cxxabiv120__si_class_type_infoE";
+  // abi::__vmi_class_type_info.
+  static const char * const VMIClassTypeInfo =
+    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+
+  const char *VTableName = nullptr;
+
+  switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    llvm_unreachable("References shouldn't get here");
+
+  case Type::Auto:
+    llvm_unreachable("Undeduced auto type shouldn't get here");
+
+  case Type::Builtin:
+  // GCC treats vector and complex types as fundamental types.
+  case Type::Vector:
+  case Type::ExtVector:
+  case Type::Complex:
+  case Type::Atomic:
+  // FIXME: GCC treats block pointers as fundamental types?!
+  case Type::BlockPointer:
+    // abi::__fundamental_type_info.
+    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
+    break;
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+    // abi::__array_type_info.
+    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // abi::__function_type_info.
+    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
+    break;
+
+  case Type::Enum:
+    // abi::__enum_type_info.
+    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
+    break;
+
+  case Type::Record: {
+    const CXXRecordDecl *RD =
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+
+    if (!RD->hasDefinition() || !RD->getNumBases()) {
+      VTableName = ClassTypeInfo;
+    } else if (CanUseSingleInheritance(RD)) {
+      VTableName = SIClassTypeInfo;
+    } else {
+      VTableName = VMIClassTypeInfo;
+    }
+
+    break;
+  }
+
+  case Type::ObjCObject:
+    // Ignore protocol qualifiers.
+    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
+
+    // Handle id and Class.
+    if (isa<BuiltinType>(Ty)) {
+      VTableName = ClassTypeInfo;
+      break;
+    }
+
+    assert(isa<ObjCInterfaceType>(Ty));
+    // Fall through.
+
+  case Type::ObjCInterface:
+    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
+      VTableName = SIClassTypeInfo;
+    } else {
+      VTableName = ClassTypeInfo;
+    }
+    break;
+
+  case Type::ObjCObjectPointer:
+  case Type::Pointer:
+    // abi::__pointer_type_info.
+    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
+    break;
+
+  case Type::MemberPointer:
+    // abi::__pointer_to_member_type_info.
+    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
+    break;
+  }
+
+  llvm::Constant *VTable =
+    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
+
+  llvm::Type *PtrDiffTy =
+    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
+
+  // The vtable address point is 2.
+  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
+  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
+  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
+
+  Fields.push_back(VTable);
+}
+
+/// \brief Return the linkage that the type info and type info name constants
+/// should have for the given type.
+static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
+                                                             QualType Ty) {
+  // Itanium C++ ABI 2.9.5p7:
+  //   In addition, it and all of the intermediate abi::__pointer_type_info
+  //   structs in the chain down to the abi::__class_type_info for the
+  //   incomplete class type must be prevented from resolving to the
+  //   corresponding type_info structs for the complete class type, possibly
+  //   by making them local static objects. Finally, a dummy class RTTI is
+  //   generated for the incomplete type that will not resolve to the final
+  //   complete class RTTI (because the latter need not exist), possibly by
+  //   making it a local static object.
+  if (ContainsIncompleteClassType(Ty))
+    return llvm::GlobalValue::InternalLinkage;
+
+  switch (Ty->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return llvm::GlobalValue::InternalLinkage;
+
+  case VisibleNoLinkage:
+  case ExternalLinkage:
+    if (!CGM.getLangOpts().RTTI) {
+      // RTTI is not enabled, which means that this type info struct is going
+      // to be used for exception handling. Give it linkonce_odr linkage.
+      return llvm::GlobalValue::LinkOnceODRLinkage;
+    }
+
+    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
+      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+      if (RD->hasAttr<WeakAttr>())
+        return llvm::GlobalValue::WeakODRLinkage;
+      if (RD->isDynamicClass())
+        return CGM.getVTableLinkage(RD);
+    }
+
+    return llvm::GlobalValue::LinkOnceODRLinkage;
+  }
+
+  llvm_unreachable("Invalid linkage!");
+}
+
+llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
+  // We want to operate on the canonical type.
+  Ty = CGM.getContext().getCanonicalType(Ty);
+
+  // Check if we've already emitted an RTTI descriptor for this type.
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
+  if (OldGV && !OldGV->isDeclaration()) {
+    assert(!OldGV->hasAvailableExternallyLinkage() &&
+           "available_externally typeinfos not yet implemented");
+
+    return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
+  }
+
+  // Check if there is already an external RTTI descriptor for this type.
+  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
+  if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
+    return GetAddrOfExternalRTTIDescriptor(Ty);
+
+  // Emit the standard library with external linkage.
+  llvm::GlobalVariable::LinkageTypes Linkage;
+  if (IsStdLib)
+    Linkage = llvm::GlobalValue::ExternalLinkage;
+  else
+    Linkage = getTypeInfoLinkage(CGM, Ty);
+
+  // Add the vtable pointer.
+  BuildVTablePointer(cast<Type>(Ty));
+
+  // And the name.
+  llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
+  llvm::Constant *TypeNameField;
+
+  // If we're supposed to demote the visibility, be sure to set a flag
+  // to use a string comparison for type_info comparisons.
+  ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
+      CXXABI.classifyRTTIUniqueness(Ty, Linkage);
+  if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
+    // The flag is the sign bit, which on ARM64 is defined to be clear
+    // for global pointers.  This is very ARM64-specific.
+    TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
+    llvm::Constant *flag =
+        llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);
+    TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
+    TypeNameField =
+        llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy);
+  } else {
+    TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
+  }
+  Fields.push_back(TypeNameField);
+
+  switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
+
+  // GCC treats vector types as fundamental types.
+  case Type::Builtin:
+  case Type::Vector:
+  case Type::ExtVector:
+  case Type::Complex:
+  case Type::BlockPointer:
+    // Itanium C++ ABI 2.9.5p4:
+    // abi::__fundamental_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    llvm_unreachable("References shouldn't get here");
+
+  case Type::Auto:
+    llvm_unreachable("Undeduced auto type shouldn't get here");
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__array_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__function_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::Enum:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__enum_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::Record: {
+    const CXXRecordDecl *RD =
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+    if (!RD->hasDefinition() || !RD->getNumBases()) {
+      // We don't need to emit any fields.
+      break;
+    }
+
+    if (CanUseSingleInheritance(RD))
+      BuildSIClassTypeInfo(RD);
+    else
+      BuildVMIClassTypeInfo(RD);
+
+    break;
+  }
+
+  case Type::ObjCObject:
+  case Type::ObjCInterface:
+    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
+    break;
+
+  case Type::ObjCObjectPointer:
+    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
+    break;
+
+  case Type::Pointer:
+    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
+    break;
+
+  case Type::MemberPointer:
+    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
+    break;
+
+  case Type::Atomic:
+    // No fields, at least for the moment.
+    break;
+  }
+
+  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
+
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+                             /*Constant=*/true, Linkage, Init, Name);
+
+  // If there's already an old global variable, replace it with the new one.
+  if (OldGV) {
+    GV->takeName(OldGV);
+    llvm::Constant *NewPtr =
+      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+    OldGV->replaceAllUsesWith(NewPtr);
+    OldGV->eraseFromParent();
+  }
+
+  // The Itanium ABI specifies that type_info objects must be globally
+  // unique, with one exception: if the type is an incomplete class
+  // type or a (possibly indirect) pointer to one.  That exception
+  // affects the general case of comparing type_info objects produced
+  // by the typeid operator, which is why the comparison operators on
+  // std::type_info generally use the type_info name pointers instead
+  // of the object addresses.  However, the language's built-in uses
+  // of RTTI generally require class types to be complete, even when
+  // manipulating pointers to those class types.  This allows the
+  // implementation of dynamic_cast to rely on address equality tests,
+  // which is much faster.
+
+  // All of this is to say that it's important that both the type_info
+  // object and the type_info name be uniqued when weakly emitted.
+
+  // Give the type_info object and name the formal visibility of the
+  // type itself.
+  llvm::GlobalValue::VisibilityTypes llvmVisibility;
+  if (llvm::GlobalValue::isLocalLinkage(Linkage))
+    // If the linkage is local, only default visibility makes sense.
+    llvmVisibility = llvm::GlobalValue::DefaultVisibility;
+  else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
+    llvmVisibility = llvm::GlobalValue::HiddenVisibility;
+  else
+    llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
+  TypeName->setVisibility(llvmVisibility);
+  GV->setVisibility(llvmVisibility);
+
+  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+}
+
+/// ComputeQualifierFlags - Compute the pointer type info flags from the
+/// given qualifier.
+static unsigned ComputeQualifierFlags(Qualifiers Quals) {
+  unsigned Flags = 0;
+
+  if (Quals.hasConst())
+    Flags |= ItaniumRTTIBuilder::PTI_Const;
+  if (Quals.hasVolatile())
+    Flags |= ItaniumRTTIBuilder::PTI_Volatile;
+  if (Quals.hasRestrict())
+    Flags |= ItaniumRTTIBuilder::PTI_Restrict;
+
+  return Flags;
+}
+
+/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
+/// for the given Objective-C object type.
+void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
+  // Drop qualifiers.
+  const Type *T = OT->getBaseType().getTypePtr();
+  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
+
+  // The builtin types are abi::__class_type_infos and don't require
+  // extra fields.
+  if (isa<BuiltinType>(T)) return;
+
+  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
+  ObjCInterfaceDecl *Super = Class->getSuperClass();
+
+  // Root classes are also __class_type_info.
+  if (!Super) return;
+
+  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
+
+  // Everything else is single inheritance.
+  llvm::Constant *BaseTypeInfo =
+      ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(SuperTy);
+  Fields.push_back(BaseTypeInfo);
+}
+
+/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
+/// inheritance, according to the Itanium C++ ABI, 2.95p6b.
+void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
+  // Itanium C++ ABI 2.9.5p6b:
+  // It adds to abi::__class_type_info a single member pointing to the
+  // type_info structure for the base type,
+  llvm::Constant *BaseTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType());
+  Fields.push_back(BaseTypeInfo);
+}
+
+namespace {
+  /// SeenBases - Contains virtual and non-virtual bases seen when traversing
+  /// a class hierarchy.
+  struct SeenBases {
+    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
+    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
+  };
+}
+
+/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
+/// abi::__vmi_class_type_info.
+///
+static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base,
+                                             SeenBases &Bases) {
+
+  unsigned Flags = 0;
+
+  const CXXRecordDecl *BaseDecl =
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+
+  if (Base->isVirtual()) {
+    // Mark the virtual base as seen.
+    if (!Bases.VirtualBases.insert(BaseDecl)) {
+      // If this virtual base has been seen before, then the class is diamond
+      // shaped.
+      Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
+    } else {
+      if (Bases.NonVirtualBases.count(BaseDecl))
+        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    }
+  } else {
+    // Mark the non-virtual base as seen.
+    if (!Bases.NonVirtualBases.insert(BaseDecl)) {
+      // If this non-virtual base has been seen before, then the class has non-
+      // diamond shaped repeated inheritance.
+      Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    } else {
+      if (Bases.VirtualBases.count(BaseDecl))
+        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    }
+  }
+
+  // Walk all bases.
+  for (const auto &I : BaseDecl->bases())
+    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
+
+  return Flags;
+}
+
+static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
+  unsigned Flags = 0;
+  SeenBases Bases;
+
+  // Walk all bases.
+  for (const auto &I : RD->bases())
+    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
+
+  return Flags;
+}
+
+/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
+/// classes with bases that do not satisfy the abi::__si_class_type_info
+/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
+void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __flags is a word with flags describing details about the class
+  //   structure, which may be referenced by using the __flags_masks
+  //   enumeration. These flags refer to both direct and indirect bases.
+  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __base_count is a word with the number of direct proper base class
+  //   descriptions that follow.
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
+
+  if (!RD->getNumBases())
+    return;
+
+  llvm::Type *LongLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().LongTy);
+
+  // Now add the base class descriptions.
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __base_info[] is an array of base class descriptions -- one for every
+  //   direct proper base. Each description is of the type:
+  //
+  //   struct abi::__base_class_type_info {
+  //   public:
+  //     const __class_type_info *__base_type;
+  //     long __offset_flags;
+  //
+  //     enum __offset_flags_masks {
+  //       __virtual_mask = 0x1,
+  //       __public_mask = 0x2,
+  //       __offset_shift = 8
+  //     };
+  //   };
+  for (const auto &Base : RD->bases()) {
+    // The __base_type member points to the RTTI for the base type.
+    Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()));
+
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
+
+    int64_t OffsetFlags = 0;
+
+    // All but the lower 8 bits of __offset_flags are a signed offset.
+    // For a non-virtual base, this is the offset in the object of the base
+    // subobject. For a virtual base, this is the offset in the virtual table of
+    // the virtual base offset for the virtual base referenced (negative).
+    CharUnits Offset;
+    if (Base.isVirtual())
+      Offset =
+        CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
+    else {
+      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+      Offset = Layout.getBaseClassOffset(BaseDecl);
+    };
+
+    OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
+
+    // The low-order byte of __offset_flags contains flags, as given by the
+    // masks from the enumeration __offset_flags_masks.
+    if (Base.isVirtual())
+      OffsetFlags |= BCTI_Virtual;
+    if (Base.getAccessSpecifier() == AS_public)
+      OffsetFlags |= BCTI_Public;
+
+    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
+  }
+}
+
+/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
+/// used for pointer types.
+void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
+  Qualifiers Quals;
+  QualType UnqualifiedPointeeTy =
+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __flags is a flag word describing the cv-qualification and other
+  //   attributes of the type pointed to
+  unsigned Flags = ComputeQualifierFlags(Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
+  //   incomplete class type, the incomplete target type flag is set.
+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
+    Flags |= PTI_Incomplete;
+
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p7:
+  //  __pointee is a pointer to the std::type_info derivation for the
+  //  unqualified type being pointed to.
+  llvm::Constant *PointeeTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
+  Fields.push_back(PointeeTypeInfo);
+}
+
+/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
+/// struct, used for member pointer types.
+void
+ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
+  QualType PointeeTy = Ty->getPointeeType();
+
+  Qualifiers Quals;
+  QualType UnqualifiedPointeeTy =
+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __flags is a flag word describing the cv-qualification and other
+  //   attributes of the type pointed to.
+  unsigned Flags = ComputeQualifierFlags(Quals);
+
+  const RecordType *ClassType = cast<RecordType>(Ty->getClass());
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
+  //   incomplete class type, the incomplete target type flag is set.
+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
+    Flags |= PTI_Incomplete;
+
+  if (IsIncompleteClassType(ClassType))
+    Flags |= PTI_ContainingClassIncomplete;
+
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __pointee is a pointer to the std::type_info derivation for the
+  //   unqualified type being pointed to.
+  llvm::Constant *PointeeTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
+  Fields.push_back(PointeeTypeInfo);
+
+  // Itanium C++ ABI 2.9.5p9:
+  //   __context is a pointer to an abi::__class_type_info corresponding to the
+  //   class type containing the member pointed to
+  //   (e.g., the "A" in "int A::*").
+  Fields.push_back(
+      ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(QualType(ClassType, 0)));
+}
+
+llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
+  return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
+}
+
+void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(QualType Type) {
+  QualType PointerType = getContext().getPointerType(Type);
+  QualType PointerTypeConst = getContext().getPointerType(Type.withConst());
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(Type, true);
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, true);
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
+}
+
+void ItaniumCXXABI::EmitFundamentalRTTIDescriptors() {
+  QualType FundamentalTypes[] = {
+      getContext().VoidTy,             getContext().NullPtrTy,
+      getContext().BoolTy,             getContext().WCharTy,
+      getContext().CharTy,             getContext().UnsignedCharTy,
+      getContext().SignedCharTy,       getContext().ShortTy,
+      getContext().UnsignedShortTy,    getContext().IntTy,
+      getContext().UnsignedIntTy,      getContext().LongTy,
+      getContext().UnsignedLongTy,     getContext().LongLongTy,
+      getContext().UnsignedLongLongTy, getContext().HalfTy,
+      getContext().FloatTy,            getContext().DoubleTy,
+      getContext().LongDoubleTy,       getContext().Char16Ty,
+      getContext().Char32Ty,
+  };
+  for (const QualType &FundamentalType : FundamentalTypes)
+    EmitFundamentalRTTIDescriptor(FundamentalType);
+}
+
+/// What sort of uniqueness rules should we use for the RTTI for the
+/// given type?
+ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
+    QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const {
+  if (shouldRTTIBeUnique())
+    return RUK_Unique;
+
+  // It's only necessary for linkonce_odr or weak_odr linkage.
+  if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
+      Linkage != llvm::GlobalValue::WeakODRLinkage)
+    return RUK_Unique;
+
+  // It's only necessary with default visibility.
+  if (CanTy->getVisibility() != DefaultVisibility)
+    return RUK_Unique;
+
+  // If we're not required to publish this symbol, hide it.
+  if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
+    return RUK_NonUniqueHidden;
+
+  // If we're required to publish this symbol, as we might be under an
+  // explicit instantiation, leave it with default visibility but
+  // enable string-comparisons.
+  assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
+  return RUK_NonUniqueVisible;
+}
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index dee565a..5243864 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -20,7 +20,9 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/VTableBuilder.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/IR/CallSite.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -35,7 +37,10 @@
 
 class MicrosoftCXXABI : public CGCXXABI {
 public:
-  MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
+  MicrosoftCXXABI(CodeGenModule &CGM)
+      : CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
+        ClassHierarchyDescriptorType(nullptr),
+        CompleteObjectLocatorType(nullptr) {}
 
   bool HasThisReturn(GlobalDecl GD) const override;
 
@@ -56,6 +61,31 @@
                                       llvm::Value *ptr,
                                       QualType type) override;
 
+  llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
+                                                   const VPtrInfo *Info);
+
+  llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
+
+  bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
+  void EmitBadTypeidCall(CodeGenFunction &CGF) override;
+  llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
+                          llvm::Value *ThisPtr,
+                          llvm::Type *StdTypeInfoPtrTy) override;
+
+  bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                          QualType SrcRecordTy) override;
+
+  llvm::Value *EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
+                                   QualType SrcRecordTy, QualType DestTy,
+                                   QualType DestRecordTy,
+                                   llvm::BasicBlock *CastEnd) override;
+
+  llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF, llvm::Value *Value,
+                                     QualType SrcRecordTy,
+                                     QualType DestTy) override;
+
+  bool EmitBadCastCall(CodeGenFunction &CGF) override;
+
   llvm::Value *
   GetVirtualBaseClassOffset(CodeGenFunction &CGF, llvm::Value *This,
                             const CXXRecordDecl *ClassDecl,
@@ -201,8 +231,20 @@
   void emitVBTableDefinition(const VPtrInfo &VBT, const CXXRecordDecl *RD,
                              llvm::GlobalVariable *GV) const;
 
-  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) override {
-    Thunk->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
+  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
+                       GlobalDecl GD, bool ReturnAdjustment) override {
+    // Never dllimport/dllexport thunks.
+    Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+
+    GVALinkage Linkage =
+        getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.getDecl()));
+
+    if (Linkage == GVA_Internal)
+      Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
+    else if (ReturnAdjustment)
+      Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
+    else
+      Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
   }
 
   llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This,
@@ -251,6 +293,114 @@
                                    llvm::Value *allocPtr,
                                    CharUnits cookieSize) override;
 
+  friend struct MSRTTIBuilder;
+
+  bool isImageRelative() const {
+    return CGM.getTarget().getPointerWidth(/*AddressSpace=*/0) == 64;
+  }
+
+  // 5 routines for constructing the llvm types for MS RTTI structs.
+  llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
+    llvm::SmallString<32> TDTypeName("rtti.TypeDescriptor");
+    TDTypeName += llvm::utostr(TypeInfoString.size());
+    llvm::StructType *&TypeDescriptorType =
+        TypeDescriptorTypeMap[TypeInfoString.size()];
+    if (TypeDescriptorType)
+      return TypeDescriptorType;
+    llvm::Type *FieldTypes[] = {
+        CGM.Int8PtrPtrTy,
+        CGM.Int8PtrTy,
+        llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
+    TypeDescriptorType =
+        llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, TDTypeName);
+    return TypeDescriptorType;
+  }
+
+  llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
+    if (!isImageRelative())
+      return PtrType;
+    return CGM.IntTy;
+  }
+
+  llvm::StructType *getBaseClassDescriptorType() {
+    if (BaseClassDescriptorType)
+      return BaseClassDescriptorType;
+    llvm::Type *FieldTypes[] = {
+        getImageRelativeType(CGM.Int8PtrTy),
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
+    };
+    BaseClassDescriptorType = llvm::StructType::create(
+        CGM.getLLVMContext(), FieldTypes, "rtti.BaseClassDescriptor");
+    return BaseClassDescriptorType;
+  }
+
+  llvm::StructType *getClassHierarchyDescriptorType() {
+    if (ClassHierarchyDescriptorType)
+      return ClassHierarchyDescriptorType;
+    // Forward-declare RTTIClassHierarchyDescriptor to break a cycle.
+    ClassHierarchyDescriptorType = llvm::StructType::create(
+        CGM.getLLVMContext(), "rtti.ClassHierarchyDescriptor");
+    llvm::Type *FieldTypes[] = {
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        getImageRelativeType(
+            getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
+    };
+    ClassHierarchyDescriptorType->setBody(FieldTypes);
+    return ClassHierarchyDescriptorType;
+  }
+
+  llvm::StructType *getCompleteObjectLocatorType() {
+    if (CompleteObjectLocatorType)
+      return CompleteObjectLocatorType;
+    CompleteObjectLocatorType = llvm::StructType::create(
+        CGM.getLLVMContext(), "rtti.CompleteObjectLocator");
+    llvm::Type *FieldTypes[] = {
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        getImageRelativeType(CGM.Int8PtrTy),
+        getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
+        getImageRelativeType(CompleteObjectLocatorType),
+    };
+    llvm::ArrayRef<llvm::Type *> FieldTypesRef(FieldTypes);
+    if (!isImageRelative())
+      FieldTypesRef = FieldTypesRef.drop_back();
+    CompleteObjectLocatorType->setBody(FieldTypesRef);
+    return CompleteObjectLocatorType;
+  }
+
+  llvm::GlobalVariable *getImageBase() {
+    StringRef Name = "__ImageBase";
+    if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
+      return GV;
+
+    return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
+                                    /*isConstant=*/true,
+                                    llvm::GlobalValue::ExternalLinkage,
+                                    /*Initializer=*/nullptr, Name);
+  }
+
+  llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
+    if (!isImageRelative())
+      return PtrVal;
+
+    llvm::Constant *ImageBaseAsInt =
+        llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
+    llvm::Constant *PtrValAsInt =
+        llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
+    llvm::Constant *Diff =
+        llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
+                                   /*HasNUW=*/true, /*HasNSW=*/true);
+    return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
+  }
+
 private:
   MicrosoftMangleContext &getMangleContext() {
     return cast<MicrosoftMangleContext>(CodeGen::CGCXXABI::getMangleContext());
@@ -370,9 +520,11 @@
 
 private:
   typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
-  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VFTablesMapTy;
+  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
+  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
   /// \brief All the vftables that have been referenced.
   VFTablesMapTy VFTablesMap;
+  VTablesMapTy VTablesMap;
 
   /// \brief This set holds the record decls we've deferred vtable emission for.
   llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
@@ -392,6 +544,11 @@
   /// Map from DeclContext to the current guard variable.  We assume that the
   /// AST is visited in source code order.
   llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
+
+  llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
+  llvm::StructType *BaseClassDescriptorType;
+  llvm::StructType *ClassHierarchyDescriptorType;
+  llvm::StructType *CompleteObjectLocatorType;
 };
 
 }
@@ -457,6 +614,129 @@
   return ptr;
 }
 
+/// \brief Gets the offset to the virtual base that contains the vfptr for
+/// MS-ABI polymorphic types.
+static llvm::Value *getPolymorphicOffset(CodeGenFunction &CGF,
+                                         const CXXRecordDecl *RD,
+                                         llvm::Value *Value) {
+  const ASTContext &Context = RD->getASTContext();
+  for (const CXXBaseSpecifier &Base : RD->vbases())
+    if (Context.getASTRecordLayout(Base.getType()->getAsCXXRecordDecl())
+            .hasExtendableVFPtr())
+      return CGF.CGM.getCXXABI().GetVirtualBaseClassOffset(
+          CGF, Value, RD, Base.getType()->getAsCXXRecordDecl());
+  llvm_unreachable("One of our vbases should be polymorphic.");
+}
+
+static std::pair<llvm::Value *, llvm::Value *>
+performBaseAdjustment(CodeGenFunction &CGF, llvm::Value *Value,
+                      QualType SrcRecordTy) {
+  Value = CGF.Builder.CreateBitCast(Value, CGF.Int8PtrTy);
+  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
+
+  if (CGF.getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
+    return std::make_pair(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0));
+
+  // Perform a base adjustment.
+  llvm::Value *Offset = getPolymorphicOffset(CGF, SrcDecl, Value);
+  Value = CGF.Builder.CreateInBoundsGEP(Value, Offset);
+  Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty);
+  return std::make_pair(Value, Offset);
+}
+
+bool MicrosoftCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
+                                                QualType SrcRecordTy) {
+  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
+  return IsDeref &&
+         !CGM.getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
+}
+
+static llvm::CallSite emitRTtypeidCall(CodeGenFunction &CGF,
+                                       llvm::Value *Argument) {
+  llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
+  llvm::FunctionType *FTy =
+      llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false);
+  llvm::Value *Args[] = {Argument};
+  llvm::Constant *Fn = CGF.CGM.CreateRuntimeFunction(FTy, "__RTtypeid");
+  return CGF.EmitRuntimeCallOrInvoke(Fn, Args);
+}
+
+void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
+  llvm::CallSite Call =
+      emitRTtypeidCall(CGF, llvm::Constant::getNullValue(CGM.VoidPtrTy));
+  Call.setDoesNotReturn();
+  CGF.Builder.CreateUnreachable();
+}
+
+llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
+                                         QualType SrcRecordTy,
+                                         llvm::Value *ThisPtr,
+                                         llvm::Type *StdTypeInfoPtrTy) {
+  llvm::Value *Offset;
+  std::tie(ThisPtr, Offset) = performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
+  return CGF.Builder.CreateBitCast(
+      emitRTtypeidCall(CGF, ThisPtr).getInstruction(), StdTypeInfoPtrTy);
+}
+
+bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                                         QualType SrcRecordTy) {
+  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
+  return SrcIsPtr &&
+         !CGM.getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
+}
+
+llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
+    CodeGenFunction &CGF, llvm::Value *Value, QualType SrcRecordTy,
+    QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
+  llvm::Type *DestLTy = CGF.ConvertType(DestTy);
+
+  llvm::Value *SrcRTTI =
+      CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
+  llvm::Value *DestRTTI =
+      CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
+
+  llvm::Value *Offset;
+  std::tie(Value, Offset) = performBaseAdjustment(CGF, Value, SrcRecordTy);
+
+  // PVOID __RTDynamicCast(
+  //   PVOID inptr,
+  //   LONG VfDelta,
+  //   PVOID SrcType,
+  //   PVOID TargetType,
+  //   BOOL isReference)
+  llvm::Type *ArgTypes[] = {CGF.Int8PtrTy, CGF.Int32Ty, CGF.Int8PtrTy,
+                            CGF.Int8PtrTy, CGF.Int32Ty};
+  llvm::Constant *Function = CGF.CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
+      "__RTDynamicCast");
+  llvm::Value *Args[] = {
+      Value, Offset, SrcRTTI, DestRTTI,
+      llvm::ConstantInt::get(CGF.Int32Ty, DestTy->isReferenceType())};
+  Value = CGF.EmitRuntimeCallOrInvoke(Function, Args).getInstruction();
+  return CGF.Builder.CreateBitCast(Value, DestLTy);
+}
+
+llvm::Value *
+MicrosoftCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, llvm::Value *Value,
+                                       QualType SrcRecordTy,
+                                       QualType DestTy) {
+  llvm::Value *Offset;
+  std::tie(Value, Offset) = performBaseAdjustment(CGF, Value, SrcRecordTy);
+
+  // PVOID __RTCastToVoid(
+  //   PVOID inptr)
+  llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
+  llvm::Constant *Function = CGF.CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
+      "__RTCastToVoid");
+  llvm::Value *Args[] = {Value};
+  return CGF.EmitRuntimeCall(Function, Args);
+}
+
+bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
+  return false;
+}
+
 llvm::Value *
 MicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
                                            llvm::Value *This,
@@ -895,25 +1175,22 @@
                                             const CXXRecordDecl *RD) {
   MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
   VPtrInfoVector VFPtrs = VFTContext.getVFPtrOffsets(RD);
-  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
 
   for (VPtrInfo *Info : VFPtrs) {
     llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->FullOffsetInMDC);
     if (VTable->hasInitializer())
       continue;
-    if (getContext().getLangOpts().RTTI)
-      CGM.getMSCompleteObjectLocator(RD, Info);
+
+    llvm::Constant *RTTI = getMSCompleteObjectLocator(RD, Info);
 
     const VTableLayout &VTLayout =
       VFTContext.getVFTableLayout(RD, Info->FullOffsetInMDC);
     llvm::Constant *Init = CGVT.CreateVTableInitializer(
         RD, VTLayout.vtable_component_begin(),
         VTLayout.getNumVTableComponents(), VTLayout.vtable_thunk_begin(),
-        VTLayout.getNumVTableThunks());
-    VTable->setInitializer(Init);
+        VTLayout.getNumVTableThunks(), RTTI);
 
-    VTable->setLinkage(Linkage);
-    CGM.setGlobalVisibility(VTable, RD);
+    VTable->setInitializer(Init);
   }
 }
 
@@ -922,8 +1199,9 @@
     const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {
   NeedsVirtualOffset = (NearestVBase != nullptr);
 
-  llvm::Value *VTableAddressPoint =
-      getAddrOfVTable(VTableClass, Base.getBaseOffset());
+  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
+  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
+  llvm::GlobalValue *VTableAddressPoint = VFTablesMap[ID];
   if (!VTableAddressPoint) {
     assert(Base.getBase()->getNumVBases() &&
            !CGM.getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr());
@@ -940,9 +1218,11 @@
 
 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
     BaseSubobject Base, const CXXRecordDecl *VTableClass) {
-  llvm::Constant *VTable = getAddrOfVTable(VTableClass, Base.getBaseOffset());
-  assert(VTable && "Couldn't find a vftable for the given base?");
-  return VTable;
+  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
+  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
+  llvm::GlobalValue *VFTable = VFTablesMap[ID];
+  assert(VFTable && "Couldn't find a vftable for the given base?");
+  return VFTable;
 }
 
 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
@@ -951,9 +1231,9 @@
   // shouldn't be used in the given record type. We want to cache this result in
   // VFTablesMap, thus a simple zero check is not sufficient.
   VFTableIdTy ID(RD, VPtrOffset);
-  VFTablesMapTy::iterator I;
+  VTablesMapTy::iterator I;
   bool Inserted;
-  std::tie(I, Inserted) = VFTablesMap.insert(std::make_pair(ID, nullptr));
+  std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID, nullptr));
   if (!Inserted)
     return I->second;
 
@@ -983,17 +1263,94 @@
   for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
     if (VFPtrs[J]->FullOffsetInMDC != VPtrOffset)
       continue;
+    SmallString<256> VFTableName;
+    mangleVFTableName(getMangleContext(), RD, VFPtrs[J], VFTableName);
+    StringRef VTableName = VFTableName;
 
-    llvm::ArrayType *ArrayType = llvm::ArrayType::get(
-        CGM.Int8PtrTy,
+    uint64_t NumVTableSlots =
         VTContext.getVFTableLayout(RD, VFPtrs[J]->FullOffsetInMDC)
-            .getNumVTableComponents());
+            .getNumVTableComponents();
+    llvm::GlobalValue::LinkageTypes VTableLinkage =
+        llvm::GlobalValue::ExternalLinkage;
+    llvm::ArrayType *VTableType =
+        llvm::ArrayType::get(CGM.Int8PtrTy, NumVTableSlots);
+    if (getContext().getLangOpts().RTTIData) {
+      VTableLinkage = llvm::GlobalValue::PrivateLinkage;
+      VTableName = "";
+    }
 
-    SmallString<256> Name;
-    mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name);
-    VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
-        Name.str(), ArrayType, llvm::GlobalValue::ExternalLinkage);
-    VTable->setUnnamedAddr(true);
+    VTable = CGM.getModule().getNamedGlobal(VFTableName);
+    if (!VTable) {
+      // Create a backing variable for the contents of VTable.  The VTable may
+      // or may not include space for a pointer to RTTI data.
+      llvm::GlobalValue *VFTable = VTable = new llvm::GlobalVariable(
+          CGM.getModule(), VTableType, /*isConstant=*/true, VTableLinkage,
+          /*Initializer=*/nullptr, VTableName);
+      VTable->setUnnamedAddr(true);
+
+      // Only insert a pointer into the VFTable for RTTI data if we are not
+      // importing it.  We never reference the RTTI data directly so there is no
+      // need to make room for it.
+      if (getContext().getLangOpts().RTTIData &&
+          !RD->hasAttr<DLLImportAttr>()) {
+        llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
+                                     llvm::ConstantInt::get(CGM.IntTy, 1)};
+        // Create a GEP which points just after the first entry in the VFTable,
+        // this should be the location of the first virtual method.
+        llvm::Constant *VTableGEP =
+            llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, GEPIndices);
+        // The symbol for the VFTable is an alias to the GEP.  It is
+        // transparent, to other modules, what the nature of this symbol is; all
+        // that matters is that the alias be the address of the first virtual
+        // method.
+        VFTable = llvm::GlobalAlias::create(
+            cast<llvm::SequentialType>(VTableGEP->getType())->getElementType(),
+            /*AddressSpace=*/0, llvm::GlobalValue::ExternalLinkage,
+            VFTableName.str(), VTableGEP, &CGM.getModule());
+      } else {
+        // We don't need a GlobalAlias to be a symbol for the VTable if we won't
+        // be referencing any RTTI data.  The GlobalVariable will end up being
+        // an appropriate definition of the VFTable.
+        VTable->setName(VFTableName.str());
+      }
+
+      VFTable->setUnnamedAddr(true);
+      if (RD->hasAttr<DLLImportAttr>())
+        VFTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+      else if (RD->hasAttr<DLLExportAttr>())
+        VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+
+      llvm::GlobalValue::LinkageTypes VFTableLinkage = CGM.getVTableLinkage(RD);
+      if (VFTable != VTable) {
+        if (llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage)) {
+          // AvailableExternally implies that we grabbed the data from another
+          // executable.  No need to stick the alias in a Comdat.
+        } else if (llvm::GlobalValue::isLocalLinkage(VFTableLinkage)) {
+          // If it's local, it means that the virtual function table can't be
+          // referenced in another translation unit. No need to stick the alias
+          // in a Comdat.
+        } else if (llvm::GlobalValue::isWeakODRLinkage(VFTableLinkage) ||
+                   llvm::GlobalValue::isLinkOnceODRLinkage(VFTableLinkage)) {
+          // The alias is going to be dropped into a Comdat, no need to make it
+          // weak.
+          VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
+          llvm::Comdat *C =
+              CGM.getModule().getOrInsertComdat(VFTable->getName());
+          // We must indicate which VFTable is larger to support linking between
+          // translation units which do and do not have RTTI data.  The largest
+          // VFTable contains the RTTI data; translation units which reference
+          // the smaller VFTable always reference it relative to the first
+          // virtual method.
+          C->setSelectionKind(llvm::Comdat::Largest);
+          VTable->setComdat(C);
+        } else {
+          llvm_unreachable("unexpected linkage for vftable!");
+        }
+      }
+      VFTable->setLinkage(VFTableLinkage);
+      CGM.setGlobalVisibility(VFTable, RD);
+      VFTablesMap[ID] = VFTable;
+    }
     break;
   }
 
@@ -1155,9 +1512,7 @@
                                   llvm::GlobalVariable::LinkageTypes Linkage) {
   SmallString<256> OutName;
   llvm::raw_svector_ostream Out(OutName);
-  MicrosoftMangleContext &Mangler =
-      cast<MicrosoftMangleContext>(CGM.getCXXABI().getMangleContext());
-  Mangler.mangleCXXVBTable(RD, VBT.MangledPath, Out);
+  getMangleContext().mangleCXXVBTable(RD, VBT.MangledPath, Out);
   Out.flush();
   StringRef Name = OutName.str();
 
@@ -1169,6 +1524,12 @@
   llvm::GlobalVariable *GV =
       CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, Linkage);
   GV->setUnnamedAddr(true);
+
+  if (RD->hasAttr<DLLImportAttr>())
+    GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+  else if (RD->hasAttr<DLLExportAttr>())
+    GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+
   return GV;
 }
 
@@ -1402,12 +1763,13 @@
       Out.flush();
     }
 
-    // Create the guard variable with a zero-initializer.  Just absorb linkage
-    // and visibility from the guarded variable.
+    // Create the guard variable with a zero-initializer. Just absorb linkage,
+    // visibility and dll storage class from the guarded variable.
     GI->Guard =
         new llvm::GlobalVariable(CGM.getModule(), GuardTy, false,
                                  GV->getLinkage(), Zero, GuardName.str());
     GI->Guard->setVisibility(GV->getVisibility());
+    GI->Guard->setDLLStorageClass(GV->getDLLStorageClass());
   } else {
     assert(GI->Guard->getLinkage() == GV->getLinkage() &&
            "static local from the same function had different linkage");
@@ -2122,3 +2484,398 @@
 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
   return new MicrosoftCXXABI(CGM);
 }
+
+// MS RTTI Overview:
+// The run time type information emitted by cl.exe contains 5 distinct types of
+// structures.  Many of them reference each other.
+//
+// TypeInfo:  Static classes that are returned by typeid.
+//
+// CompleteObjectLocator:  Referenced by vftables.  They contain information
+//   required for dynamic casting, including OffsetFromTop.  They also contain
+//   a reference to the TypeInfo for the type and a reference to the
+//   CompleteHierarchyDescriptor for the type.
+//
+// ClassHieararchyDescriptor: Contains information about a class hierarchy.
+//   Used during dynamic_cast to walk a class hierarchy.  References a base
+//   class array and the size of said array.
+//
+// BaseClassArray: Contains a list of classes in a hierarchy.  BaseClassArray is
+//   somewhat of a misnomer because the most derived class is also in the list
+//   as well as multiple copies of virtual bases (if they occur multiple times
+//   in the hiearchy.)  The BaseClassArray contains one BaseClassDescriptor for
+//   every path in the hierarchy, in pre-order depth first order.  Note, we do
+//   not declare a specific llvm type for BaseClassArray, it's merely an array
+//   of BaseClassDescriptor pointers.
+//
+// BaseClassDescriptor: Contains information about a class in a class hierarchy.
+//   BaseClassDescriptor is also somewhat of a misnomer for the same reason that
+//   BaseClassArray is.  It contains information about a class within a
+//   hierarchy such as: is this base is ambiguous and what is its offset in the
+//   vbtable.  The names of the BaseClassDescriptors have all of their fields
+//   mangled into them so they can be aggressively deduplicated by the linker.
+
+static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {
+  StringRef MangledName("\01??_7type_info@@6B@");
+  if (auto VTable = CGM.getModule().getNamedGlobal(MangledName))
+    return VTable;
+  return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
+                                  /*Constant=*/true,
+                                  llvm::GlobalVariable::ExternalLinkage,
+                                  /*Initializer=*/nullptr, MangledName);
+}
+
+namespace {
+
+/// \brief A Helper struct that stores information about a class in a class
+/// hierarchy.  The information stored in these structs struct is used during
+/// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
+// During RTTI creation, MSRTTIClasses are stored in a contiguous array with
+// implicit depth first pre-order tree connectivity.  getFirstChild and
+// getNextSibling allow us to walk the tree efficiently.
+struct MSRTTIClass {
+  enum {
+    IsPrivateOnPath = 1 | 8,
+    IsAmbiguous = 2,
+    IsPrivate = 4,
+    IsVirtual = 16,
+    HasHierarchyDescriptor = 64
+  };
+  MSRTTIClass(const CXXRecordDecl *RD) : RD(RD) {}
+  uint32_t initialize(const MSRTTIClass *Parent,
+                      const CXXBaseSpecifier *Specifier);
+
+  MSRTTIClass *getFirstChild() { return this + 1; }
+  static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
+    return Child + 1 + Child->NumBases;
+  }
+
+  const CXXRecordDecl *RD, *VirtualRoot;
+  uint32_t Flags, NumBases, OffsetInVBase;
+};
+
+/// \brief Recursively initialize the base class array.
+uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
+                                 const CXXBaseSpecifier *Specifier) {
+  Flags = HasHierarchyDescriptor;
+  if (!Parent) {
+    VirtualRoot = nullptr;
+    OffsetInVBase = 0;
+  } else {
+    if (Specifier->getAccessSpecifier() != AS_public)
+      Flags |= IsPrivate | IsPrivateOnPath;
+    if (Specifier->isVirtual()) {
+      Flags |= IsVirtual;
+      VirtualRoot = RD;
+      OffsetInVBase = 0;
+    } else {
+      if (Parent->Flags & IsPrivateOnPath)
+        Flags |= IsPrivateOnPath;
+      VirtualRoot = Parent->VirtualRoot;
+      OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
+          .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
+    }
+  }
+  NumBases = 0;
+  MSRTTIClass *Child = getFirstChild();
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    NumBases += Child->initialize(this, &Base) + 1;
+    Child = getNextChild(Child);
+  }
+  return NumBases;
+}
+
+static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
+  switch (Ty->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return llvm::GlobalValue::InternalLinkage;
+
+  case VisibleNoLinkage:
+  case ExternalLinkage:
+    return llvm::GlobalValue::LinkOnceODRLinkage;
+  }
+  llvm_unreachable("Invalid linkage!");
+}
+
+/// \brief An ephemeral helper class for building MS RTTI types.  It caches some
+/// calls to the module and information about the most derived class in a
+/// hierarchy.
+struct MSRTTIBuilder {
+  enum {
+    HasBranchingHierarchy = 1,
+    HasVirtualBranchingHierarchy = 2,
+    HasAmbiguousBases = 4
+  };
+
+  MSRTTIBuilder(MicrosoftCXXABI &ABI, const CXXRecordDecl *RD)
+      : CGM(ABI.CGM), Context(CGM.getContext()),
+        VMContext(CGM.getLLVMContext()), Module(CGM.getModule()), RD(RD),
+        Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
+        ABI(ABI) {}
+
+  llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
+  llvm::GlobalVariable *
+  getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
+  llvm::GlobalVariable *getClassHierarchyDescriptor();
+  llvm::GlobalVariable *getCompleteObjectLocator(const VPtrInfo *Info);
+
+  CodeGenModule &CGM;
+  ASTContext &Context;
+  llvm::LLVMContext &VMContext;
+  llvm::Module &Module;
+  const CXXRecordDecl *RD;
+  llvm::GlobalVariable::LinkageTypes Linkage;
+  MicrosoftCXXABI &ABI;
+};
+
+} // namespace
+
+/// \brief Recursively serializes a class hierarchy in pre-order depth first
+/// order.
+static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
+                                    const CXXRecordDecl *RD) {
+  Classes.push_back(MSRTTIClass(RD));
+  for (const CXXBaseSpecifier &Base : RD->bases())
+    serializeClassHierarchy(Classes, Base.getType()->getAsCXXRecordDecl());
+}
+
+/// \brief Find ambiguity among base classes.
+static void
+detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
+  for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
+    if ((Class->Flags & MSRTTIClass::IsVirtual) &&
+        !VirtualBases.insert(Class->RD)) {
+      Class = MSRTTIClass::getNextChild(Class);
+      continue;
+    }
+    if (!UniqueBases.insert(Class->RD))
+      AmbiguousBases.insert(Class->RD);
+    Class++;
+  }
+  if (AmbiguousBases.empty())
+    return;
+  for (MSRTTIClass &Class : Classes)
+    if (AmbiguousBases.count(Class.RD))
+      Class.Flags |= MSRTTIClass::IsAmbiguous;
+}
+
+llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
+  }
+
+  // Check to see if we've already declared this ClassHierarchyDescriptor.
+  if (auto CHD = Module.getNamedGlobal(MangledName))
+    return CHD;
+
+  // Serialize the class hierarchy and initialize the CHD Fields.
+  SmallVector<MSRTTIClass, 8> Classes;
+  serializeClassHierarchy(Classes, RD);
+  Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
+  detectAmbiguousBases(Classes);
+  int Flags = 0;
+  for (auto Class : Classes) {
+    if (Class.RD->getNumBases() > 1)
+      Flags |= HasBranchingHierarchy;
+    // Note: cl.exe does not calculate "HasAmbiguousBases" correctly.  We
+    // believe the field isn't actually used.
+    if (Class.Flags & MSRTTIClass::IsAmbiguous)
+      Flags |= HasAmbiguousBases;
+  }
+  if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
+    Flags |= HasVirtualBranchingHierarchy;
+  // These gep indices are used to get the address of the first element of the
+  // base class array.
+  llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
+                               llvm::ConstantInt::get(CGM.IntTy, 0)};
+
+  // Forward-declare the class hierarchy descriptor
+  auto Type = ABI.getClassHierarchyDescriptorType();
+  auto CHD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+                                      /*Initializer=*/nullptr,
+                                      MangledName.c_str());
+
+  // Initialize the base class ClassHierarchyDescriptor.
+  llvm::Constant *Fields[] = {
+      llvm::ConstantInt::get(CGM.IntTy, 0), // Unknown
+      llvm::ConstantInt::get(CGM.IntTy, Flags),
+      llvm::ConstantInt::get(CGM.IntTy, Classes.size()),
+      ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
+          getBaseClassArray(Classes),
+          llvm::ArrayRef<llvm::Value *>(GEPIndices))),
+  };
+  CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
+  return CHD;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
+  }
+
+  // Forward-declare the base class array.
+  // cl.exe pads the base class array with 1 (in 32 bit mode) or 4 (in 64 bit
+  // mode) bytes of padding.  We provide a pointer sized amount of padding by
+  // adding +1 to Classes.size().  The sections have pointer alignment and are
+  // marked pick-any so it shouldn't matter.
+  llvm::Type *PtrType = ABI.getImageRelativeType(
+      ABI.getBaseClassDescriptorType()->getPointerTo());
+  auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
+  auto *BCA = new llvm::GlobalVariable(
+      Module, ArrType,
+      /*Constant=*/true, Linkage, /*Initializer=*/nullptr, MangledName.c_str());
+
+  // Initialize the BaseClassArray.
+  SmallVector<llvm::Constant *, 8> BaseClassArrayData;
+  for (MSRTTIClass &Class : Classes)
+    BaseClassArrayData.push_back(
+        ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
+  BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
+  BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
+  return BCA;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
+  // Compute the fields for the BaseClassDescriptor.  They are computed up front
+  // because they are mangled into the name of the object.
+  uint32_t OffsetInVBTable = 0;
+  int32_t VBPtrOffset = -1;
+  if (Class.VirtualRoot) {
+    auto &VTableContext = CGM.getMicrosoftVTableContext();
+    OffsetInVBTable = VTableContext.getVBTableIndex(RD, Class.VirtualRoot) * 4;
+    VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
+  }
+
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
+        Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
+        Class.Flags, Out);
+  }
+
+  // Check to see if we've already declared this object.
+  if (auto BCD = Module.getNamedGlobal(MangledName))
+    return BCD;
+
+  // Forward-declare the base class descriptor.
+  auto Type = ABI.getBaseClassDescriptorType();
+  auto BCD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+                                      /*Initializer=*/nullptr,
+                                      MangledName.c_str());
+
+  // Initialize the BaseClassDescriptor.
+  llvm::Constant *Fields[] = {
+      ABI.getImageRelativeConstant(
+          ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
+      llvm::ConstantInt::get(CGM.IntTy, Class.NumBases),
+      llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase),
+      llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
+      llvm::ConstantInt::get(CGM.IntTy, OffsetInVBTable),
+      llvm::ConstantInt::get(CGM.IntTy, Class.Flags),
+      ABI.getImageRelativeConstant(
+          MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
+  };
+  BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
+  return BCD;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo *Info) {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info->MangledPath, Out);
+  }
+
+  // Check to see if we've already computed this complete object locator.
+  if (auto COL = Module.getNamedGlobal(MangledName))
+    return COL;
+
+  // Compute the fields of the complete object locator.
+  int OffsetToTop = Info->FullOffsetInMDC.getQuantity();
+  int VFPtrOffset = 0;
+  // The offset includes the vtordisp if one exists.
+  if (const CXXRecordDecl *VBase = Info->getVBaseWithVPtr())
+    if (Context.getASTRecordLayout(RD)
+      .getVBaseOffsetsMap()
+      .find(VBase)
+      ->second.hasVtorDisp())
+      VFPtrOffset = Info->NonVirtualOffset.getQuantity() + 4;
+
+  // Forward-declare the complete object locator.
+  llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
+  auto COL = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+    /*Initializer=*/nullptr, MangledName.c_str());
+
+  // Initialize the CompleteObjectLocator.
+  llvm::Constant *Fields[] = {
+      llvm::ConstantInt::get(CGM.IntTy, ABI.isImageRelative()),
+      llvm::ConstantInt::get(CGM.IntTy, OffsetToTop),
+      llvm::ConstantInt::get(CGM.IntTy, VFPtrOffset),
+      ABI.getImageRelativeConstant(
+          CGM.GetAddrOfRTTIDescriptor(Context.getTypeDeclType(RD))),
+      ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
+      ABI.getImageRelativeConstant(COL),
+  };
+  llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
+  if (!ABI.isImageRelative())
+    FieldsRef = FieldsRef.drop_back();
+  COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
+  return COL;
+}
+
+/// \brief Gets a TypeDescriptor.  Returns a llvm::Constant * rather than a
+/// llvm::GlobalVariable * because different type descriptors have different
+/// types, and need to be abstracted.  They are abstracting by casting the
+/// address to an Int8PtrTy.
+llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) {
+  SmallString<256> MangledName, TypeInfoString;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    getMangleContext().mangleCXXRTTI(Type, Out);
+  }
+
+  // Check to see if we've already declared this TypeDescriptor.
+  if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
+    return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+
+  // Compute the fields for the TypeDescriptor.
+  {
+    llvm::raw_svector_ostream Out(TypeInfoString);
+    getMangleContext().mangleCXXRTTIName(Type, Out);
+  }
+
+  // Declare and initialize the TypeDescriptor.
+  llvm::Constant *Fields[] = {
+    getTypeInfoVTable(CGM),                        // VFPtr
+    llvm::ConstantPointerNull::get(CGM.Int8PtrTy), // Runtime data
+    llvm::ConstantDataArray::getString(CGM.getLLVMContext(), TypeInfoString)};
+  llvm::StructType *TypeDescriptorType =
+      getTypeDescriptorType(TypeInfoString);
+  return llvm::ConstantExpr::getBitCast(
+      new llvm::GlobalVariable(
+          CGM.getModule(), TypeDescriptorType, /*Constant=*/false,
+          getLinkageForRTTI(Type),
+          llvm::ConstantStruct::get(TypeDescriptorType, Fields),
+          MangledName.c_str()),
+      CGM.Int8PtrTy);
+}
+
+/// \brief Gets or a creates a Microsoft CompleteObjectLocator.
+llvm::GlobalVariable *
+MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
+                                            const VPtrInfo *Info) {
+  return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
+}
diff --git a/lib/CodeGen/MicrosoftRTTI.cpp b/lib/CodeGen/MicrosoftRTTI.cpp
deleted file mode 100644
index 0eb8100..0000000
--- a/lib/CodeGen/MicrosoftRTTI.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation of RTTI descriptors.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenModule.h"
-#include "CGCXXABI.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/Type.h"
-#include "clang/Frontend/CodeGenOptions.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-// MS RTTI Overview:
-// The run time type information emitted by cl.exe contains 5 distinct types of
-// structures.  Many of them reference each other.
-//
-// TypeInfo:  Static classes that are returned by typeid.
-//
-// CompleteObjectLocator:  Referenced by vftables.  They contain information
-//   required for dynamic casting, including OffsetFromTop.  They also contain
-//   a reference to the TypeInfo for the type and a reference to the
-//   CompleteHierarchyDescriptor for the type.
-//
-// ClassHieararchyDescriptor: Contains information about a class hierarchy.
-//   Used during dynamic_cast to walk a class hierarchy.  References a base
-//   class array and the size of said array.
-//
-// BaseClassArray: Contains a list of classes in a hierarchy.  BaseClassArray is
-//   somewhat of a misnomer because the most derived class is also in the list
-//   as well as multiple copies of virtual bases (if they occur multiple times
-//   in the hiearchy.)  The BaseClassArray contains one BaseClassDescriptor for
-//   every path in the hierarchy, in pre-order depth first order.  Note, we do
-//   not declare a specific llvm type for BaseClassArray, it's merely an array
-//   of BaseClassDescriptor pointers.
-//
-// BaseClassDescriptor: Contains information about a class in a class hierarchy.
-//   BaseClassDescriptor is also somewhat of a misnomer for the same reason that
-//   BaseClassArray is.  It contains information about a class within a
-//   hierarchy such as: is this base is ambiguous and what is its offset in the
-//   vbtable.  The names of the BaseClassDescriptors have all of their fields
-//   mangled into them so they can be aggressively deduplicated by the linker.
-
-// 5 routines for constructing the llvm types for MS RTTI structs.
-static llvm::StructType *getClassHierarchyDescriptorType(CodeGenModule &CGM);
-
-static llvm::StructType *getTypeDescriptorType(CodeGenModule &CGM,
-                                               StringRef TypeInfoString) {
-  llvm::SmallString<32> TDTypeName("MSRTTITypeDescriptor");
-  TDTypeName += TypeInfoString.size();
-  if (auto Type = CGM.getModule().getTypeByName(TDTypeName))
-    return Type;
-  llvm::Type *FieldTypes[] = {
-      CGM.Int8PtrPtrTy,
-      CGM.Int8PtrTy,
-      llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
-  return llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, TDTypeName);
-}
-
-static llvm::StructType *getBaseClassDescriptorType(CodeGenModule &CGM) {
-  static const char Name[] = "MSRTTIBaseClassDescriptor";
-  if (auto Type = CGM.getModule().getTypeByName(Name))
-    return Type;
-  llvm::Type *FieldTypes[] = {
-      CGM.Int8PtrTy,
-      CGM.IntTy,
-      CGM.IntTy,
-      CGM.IntTy,
-      CGM.IntTy,
-      CGM.IntTy,
-      getClassHierarchyDescriptorType(CGM)->getPointerTo()};
-  return llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, Name);
-}
-
-static llvm::StructType *getClassHierarchyDescriptorType(CodeGenModule &CGM) {
-  static const char Name[] = "MSRTTIClassHierarchyDescriptor";
-  if (auto Type = CGM.getModule().getTypeByName(Name))
-    return Type;
-  // Forward declare RTTIClassHierarchyDescriptor to break a cycle.
-  llvm::StructType *Type = llvm::StructType::create(CGM.getLLVMContext(), Name);
-  llvm::Type *FieldTypes[] = {
-    CGM.IntTy,
-    CGM.IntTy,
-    CGM.IntTy,
-    getBaseClassDescriptorType(CGM)->getPointerTo()->getPointerTo()};
-  Type->setBody(FieldTypes);
-  return Type;
-}
-
-static llvm::StructType *getCompleteObjectLocatorType(CodeGenModule &CGM) {
-  static const char Name[] = "MSRTTICompleteObjectLocator";
-  if (auto Type = CGM.getModule().getTypeByName(Name))
-    return Type;
-  llvm::Type *FieldTypes[] = {
-    CGM.IntTy,
-    CGM.IntTy,
-    CGM.IntTy,
-    CGM.Int8PtrTy,
-    getClassHierarchyDescriptorType(CGM)->getPointerTo() };
-  return llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, Name);
-}
-
-static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {
-  StringRef MangledName("\01??_7type_info@@6B@");
-  if (auto VTable = CGM.getModule().getNamedGlobal(MangledName))
-    return VTable;
-  return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
-                                  /*Constant=*/true,
-                                  llvm::GlobalVariable::ExternalLinkage,
-                                  /*Initializer=*/0, MangledName);
-}
-
-namespace {
-
-/// \brief A Helper struct that stores information about a class in a class
-/// hierarchy.  The information stored in these structs struct is used during
-/// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
-// During RTTI creation, MSRTTIClasses are stored in a contiguous array with
-// implicit depth first pre-order tree connectivity.  getFirstChild and
-// getNextSibling allow us to walk the tree efficiently.
-struct MSRTTIClass {
-  enum {
-    IsPrivateOnPath = 1 | 8,
-    IsAmbiguous = 2,
-    IsPrivate = 4,
-    IsVirtual = 16,
-    HasHierarchyDescriptor = 64
-  };
-  MSRTTIClass(const CXXRecordDecl *RD) : RD(RD) {}
-  uint32_t initialize(const MSRTTIClass *Parent,
-                      const CXXBaseSpecifier *Specifier);
-
-  MSRTTIClass *getFirstChild() { return this + 1; }
-  static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
-    return Child + 1 + Child->NumBases;
-  }
-
-  const CXXRecordDecl *RD, *VirtualRoot;
-  uint32_t Flags, NumBases, OffsetInVBase;
-};
-
-/// \brief Recursively initialize the base class array.
-uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
-                                 const CXXBaseSpecifier *Specifier) {
-  Flags = HasHierarchyDescriptor;
-  if (!Parent) {
-    VirtualRoot = 0;
-    OffsetInVBase = 0;
-  } else {
-    if (Specifier->getAccessSpecifier() != AS_public)
-      Flags |= IsPrivate | IsPrivateOnPath;
-    if (Specifier->isVirtual()) {
-      Flags |= IsVirtual;
-      VirtualRoot = RD;
-      OffsetInVBase = 0;
-    } else {
-      if (Parent->Flags & IsPrivateOnPath)
-        Flags |= IsPrivateOnPath;
-      VirtualRoot = Parent->VirtualRoot;
-      OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
-          .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
-    }
-  }
-  NumBases = 0;
-  MSRTTIClass *Child = getFirstChild();
-  for (const CXXBaseSpecifier &Base : RD->bases()) {
-    NumBases += Child->initialize(this, &Base) + 1;
-    Child = getNextChild(Child);
-  }
-  return NumBases;
-}
-
-/// \brief An ephemeral helper class for building MS RTTI types.  It caches some
-/// calls to the module and information about the most derived class in a
-/// hierarchy.
-struct MSRTTIBuilder {
-  enum {
-    HasBranchingHierarchy = 1,
-    HasVirtualBranchingHierarchy = 2,
-    HasAmbiguousBases = 4
-  };
-
-  MSRTTIBuilder(CodeGenModule &CGM, const CXXRecordDecl *RD)
-      : CGM(CGM), Context(CGM.getContext()), VMContext(CGM.getLLVMContext()),
-        Module(CGM.getModule()), RD(RD), Linkage(CGM.getVTableLinkage(RD)),
-        Mangler(
-            cast<MicrosoftMangleContext>(CGM.getCXXABI().getMangleContext())) {}
-
-  llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
-  llvm::GlobalVariable *
-  getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
-  llvm::GlobalVariable *getClassHierarchyDescriptor();
-  llvm::GlobalVariable *getCompleteObjectLocator(const VPtrInfo *Info);
-
-  CodeGenModule &CGM;
-  ASTContext &Context;
-  llvm::LLVMContext &VMContext;
-  llvm::Module &Module;
-  const CXXRecordDecl *RD;
-  llvm::GlobalVariable::LinkageTypes Linkage;
-  MicrosoftMangleContext &Mangler;
-};
-
-} // namespace
-
-/// \brief Recursively serializes a class hierarchy in pre-order depth first
-/// order.
-static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
-                                    const CXXRecordDecl *RD) {
-  Classes.push_back(MSRTTIClass(RD));
-  for (const CXXBaseSpecifier &Base : RD->bases())
-    serializeClassHierarchy(Classes, Base.getType()->getAsCXXRecordDecl());
-}
-
-/// \brief Find ambiguity among base classes.
-static void
-detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {
-  llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
-  llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
-  llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
-  for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
-    if ((Class->Flags & MSRTTIClass::IsVirtual) &&
-        !VirtualBases.insert(Class->RD)) {
-      Class = MSRTTIClass::getNextChild(Class);
-      continue;
-    }
-    if (!UniqueBases.insert(Class->RD))
-      AmbiguousBases.insert(Class->RD);
-    Class++;
-  }
-  if (AmbiguousBases.empty())
-    return;
-  for (MSRTTIClass &Class : Classes)
-    if (AmbiguousBases.count(Class.RD))
-      Class.Flags |= MSRTTIClass::IsAmbiguous;
-}
-
-llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
-  SmallString<256> MangledName;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
-  }
-
-  // Check to see if we've already declared this ClassHierarchyDescriptor.
-  if (auto CHD = Module.getNamedGlobal(MangledName))
-    return CHD;
-
-  // Serialize the class hierarchy and initalize the CHD Fields.
-  SmallVector<MSRTTIClass, 8> Classes;
-  serializeClassHierarchy(Classes, RD);
-  Classes.front().initialize(/*Parent=*/0, /*Specifier=*/0);
-  detectAmbiguousBases(Classes);
-  int Flags = 0;
-  for (auto Class : Classes) {
-    if (Class.RD->getNumBases() > 1)
-      Flags |= HasBranchingHierarchy;
-    // Note: cl.exe does not calculate "HasAmbiguousBases" correctly.  We
-    // believe the field isn't actually used.
-    if (Class.Flags & MSRTTIClass::IsAmbiguous)
-      Flags |= HasAmbiguousBases;
-  }
-  if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
-    Flags |= HasVirtualBranchingHierarchy;
-  // These gep indices are used to get the address of the first element of the
-  // base class array.
-  llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
-                               llvm::ConstantInt::get(CGM.IntTy, 0)};
-
-  // Forward declare the class hierarchy descriptor
-  auto Type = getClassHierarchyDescriptorType(CGM);
-  auto CHD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
-                                      /*Initializer=*/0, MangledName.c_str());
-
-  // Initialize the base class ClassHierarchyDescriptor.
-  llvm::Constant *Fields[] = {
-    llvm::ConstantInt::get(CGM.IntTy, 0), // Unknown
-    llvm::ConstantInt::get(CGM.IntTy, Flags),
-    llvm::ConstantInt::get(CGM.IntTy, Classes.size()),
-    llvm::ConstantExpr::getInBoundsGetElementPtr(
-        getBaseClassArray(Classes),
-        llvm::ArrayRef<llvm::Value *>(GEPIndices))};
-  CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
-  return CHD;
-}
-
-llvm::GlobalVariable *
-MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
-  SmallString<256> MangledName;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTIBaseClassArray(RD, Out);
-  }
-
-  // Foward declare the base class array.
-  // cl.exe pads the base class array with 1 (in 32 bit mode) or 4 (in 64 bit
-  // mode) bytes of padding.  We provide a pointer sized amount of padding by
-  // adding +1 to Classes.size().  The sections have pointer alignment and are
-  // marked pick-any so it shouldn't matter.
-  auto PtrType = getBaseClassDescriptorType(CGM)->getPointerTo();
-  auto ArrayType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
-  auto BCA = new llvm::GlobalVariable(Module, ArrayType,
-      /*Constant=*/true, Linkage, /*Initializer=*/0, MangledName.c_str());
-
-  // Initialize the BaseClassArray.
-  SmallVector<llvm::Constant *, 8> BaseClassArrayData;
-  for (MSRTTIClass &Class : Classes)
-    BaseClassArrayData.push_back(getBaseClassDescriptor(Class));
-  BaseClassArrayData.push_back(llvm::ConstantPointerNull::get(PtrType));
-  BCA->setInitializer(llvm::ConstantArray::get(ArrayType, BaseClassArrayData));
-  return BCA;
-}
-
-llvm::GlobalVariable *
-MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
-  // Compute the fields for the BaseClassDescriptor.  They are computed up front
-  // because they are mangled into the name of the object.
-  uint32_t OffsetInVBTable = 0;
-  int32_t VBPtrOffset = -1;
-  if (Class.VirtualRoot) {
-    auto &VTableContext = CGM.getMicrosoftVTableContext();
-    OffsetInVBTable = VTableContext.getVBTableIndex(RD, Class.VirtualRoot) * 4;
-    VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
-  }
-
-  SmallString<256> MangledName;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTIBaseClassDescriptor(Class.RD, Class.OffsetInVBase,
-                                             VBPtrOffset, OffsetInVBTable,
-                                             Class.Flags, Out);
-  }
-
-  // Check to see if we've already declared declared this object.
-  if (auto BCD = Module.getNamedGlobal(MangledName))
-    return BCD;
-
-  // Forward declare the base class descriptor.
-  auto Type = getBaseClassDescriptorType(CGM);
-  auto BCD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
-                                      /*Initializer=*/0, MangledName.c_str());
-
-  // Initialize the BaseClassDescriptor.
-  llvm::Constant *Fields[] = {
-    CGM.getMSTypeDescriptor(Context.getTypeDeclType(Class.RD)),
-    llvm::ConstantInt::get(CGM.IntTy, Class.NumBases),
-    llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase),
-    llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
-    llvm::ConstantInt::get(CGM.IntTy, OffsetInVBTable),
-    llvm::ConstantInt::get(CGM.IntTy, Class.Flags),
-    MSRTTIBuilder(CGM, Class.RD).getClassHierarchyDescriptor()};
-  BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
-  return BCD;
-}
-
-llvm::GlobalVariable *
-MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo *Info) {
-  SmallString<256> MangledName;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTICompleteObjectLocator(RD, Info->MangledPath, Out);
-  }
-
-  // Check to see if we've already computed this complete object locator.
-  if (auto COL = Module.getNamedGlobal(MangledName))
-    return COL;
-
-  // Compute the fields of the complete object locator.
-  int OffsetToTop = Info->FullOffsetInMDC.getQuantity();
-  int VFPtrOffset = 0;
-  // The offset includes the vtordisp if one exists.
-  if (const CXXRecordDecl *VBase = Info->getVBaseWithVPtr())
-    if (Context.getASTRecordLayout(RD)
-      .getVBaseOffsetsMap()
-      .find(VBase)
-      ->second.hasVtorDisp())
-      VFPtrOffset = Info->NonVirtualOffset.getQuantity() + 4;
-
-  // Forward declare the complete object locator.
-  llvm::StructType *Type = getCompleteObjectLocatorType(CGM);
-  auto COL = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
-    /*Initializer=*/0, MangledName.c_str());
-
-  // Initialize the CompleteObjectLocator.
-  llvm::Constant *Fields[] = {
-    llvm::ConstantInt::get(CGM.IntTy, 0), // IsDeltaEncoded
-    llvm::ConstantInt::get(CGM.IntTy, OffsetToTop),
-    llvm::ConstantInt::get(CGM.IntTy, VFPtrOffset),
-    CGM.getMSTypeDescriptor(Context.getTypeDeclType(RD)),
-    getClassHierarchyDescriptor()};
-  COL->setInitializer(llvm::ConstantStruct::get(Type, Fields));
-  return COL;
-}
-
-
-/// \brief Gets a TypeDescriptor.  Returns a llvm::Constant * rather than a
-/// llvm::GlobalVariable * because different type descriptors have different
-/// types, and need to be abstracted.  They are abstracting by casting the
-/// address to an Int8PtrTy.
-llvm::Constant *CodeGenModule::getMSTypeDescriptor(QualType Type) {
-  auto &Mangler(cast<MicrosoftMangleContext>(getCXXABI().getMangleContext()));
-  SmallString<256> MangledName, TypeInfoString;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTI(Type, Out);
-  }
-
-  // Check to see if we've already declared this TypeDescriptor.
-  if (auto TypeDescriptor = getModule().getNamedGlobal(MangledName))
-    return llvm::ConstantExpr::getBitCast(TypeDescriptor, Int8PtrTy);
-
-  // Compute the fields for the TypeDescriptor.
-  {
-    llvm::raw_svector_ostream Out(TypeInfoString);
-    Mangler.mangleCXXRTTIName(Type, Out);
-  }
-
-  // Declare and initialize the TypeDescriptor.
-  llvm::Constant *Fields[] = {
-    getTypeInfoVTable(*this),                  // VFPtr
-    llvm::ConstantPointerNull::get(Int8PtrTy), // Runtime data
-    llvm::ConstantDataArray::getString(VMContext, TypeInfoString)};
-  auto TypeDescriptorType = getTypeDescriptorType(*this, TypeInfoString);
-  return llvm::ConstantExpr::getBitCast(
-      new llvm::GlobalVariable(
-          getModule(), TypeDescriptorType, /*Constant=*/false,
-          getTypeInfoLinkage(Type),
-          llvm::ConstantStruct::get(TypeDescriptorType, Fields),
-          MangledName.c_str()),
-      Int8PtrTy);
-}
-
-llvm::GlobalVariable *
-CodeGenModule::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
-                                          const VPtrInfo *Info) {
-  return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
-}
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 78cb82d..c4a0e5c 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -49,6 +49,21 @@
       return M.get();
     }
 
+    const Decl *GetDeclForMangledName(StringRef MangledName) override {
+      GlobalDecl Result;
+      if (!Builder->lookupRepresentativeDecl(MangledName, Result))
+        return nullptr;
+      const Decl *D = Result.getCanonicalDecl().getDecl();
+      if (auto FD = dyn_cast<FunctionDecl>(D)) {
+        if (FD->hasBody(FD))
+          return FD;
+      } else if (auto TD = dyn_cast<TagDecl>(D)) {
+        if (auto Def = TD->getDefinition())
+          return Def;
+      }
+      return D;
+    }
+
     llvm::Module *ReleaseModule() override { return M.release(); }
 
     void Initialize(ASTContext &Context) override {
@@ -78,6 +93,12 @@
       // Make sure to emit all elements of a Decl.
       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
         Builder->EmitTopLevelDecl(*I);
+
+      // Emit any deferred inline method definitions.
+      for (CXXMethodDecl *MD : DeferredInlineMethodDefinitions)
+        Builder->EmitTopLevelDecl(MD);
+      DeferredInlineMethodDefinitions.clear();
+
       return true;
     }
 
@@ -87,12 +108,15 @@
 
       assert(D->doesThisDeclarationHaveABody());
 
-      // We may have member functions that need to be emitted at this point.
-      if (!D->isDependentContext() &&
-          (D->hasAttr<UsedAttr>() || D->hasAttr<ConstructorAttr>() ||
-           D->hasAttr<DLLExportAttr>())) {
-        Builder->EmitTopLevelDecl(D);
-      }
+      // We may want to emit this definition. However, that decision might be
+      // based on computing the linkage, and we have to defer that in case we
+      // are inside of something that will change the method's final linkage,
+      // e.g.
+      //   typedef struct {
+      //     void bar();
+      //     void foo() { bar(); }
+      //   } A;
+      DeferredInlineMethodDefinitions.push_back(D);
     }
 
     /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
@@ -153,6 +177,9 @@
     void HandleDependentLibrary(llvm::StringRef Lib) override {
       Builder->AddDependentLib(Lib);
     }
+
+  private:
+    std::vector<CXXMethodDecl *> DeferredInlineMethodDefinitions;
   };
 }
 
diff --git a/lib/CodeGen/SanitizerBlacklist.cpp b/lib/CodeGen/SanitizerBlacklist.cpp
new file mode 100644
index 0000000..60bdbe1
--- /dev/null
+++ b/lib/CodeGen/SanitizerBlacklist.cpp
@@ -0,0 +1,48 @@
+//===--- SanitizerBlacklist.cpp - Blacklist for sanitizers ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided blacklist used to disable/alter instrumentation done in
+// sanitizers.
+//
+//===----------------------------------------------------------------------===//
+#include "SanitizerBlacklist.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Module.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+static StringRef GetGlobalTypeString(const llvm::GlobalValue &G) {
+  // Types of GlobalVariables are always pointer types.
+  llvm::Type *GType = G.getType()->getElementType();
+  // For now we support blacklisting struct types only.
+  if (llvm::StructType *SGType = dyn_cast<llvm::StructType>(GType)) {
+    if (!SGType->isLiteral())
+      return SGType->getName();
+  }
+  return "<unknown type>";
+}
+
+bool SanitizerBlacklist::isIn(const llvm::Module &M,
+                              const StringRef Category) const {
+  return SCL->inSection("src", M.getModuleIdentifier(), Category);
+}
+
+bool SanitizerBlacklist::isIn(const llvm::Function &F) const {
+  return isIn(*F.getParent()) ||
+         SCL->inSection("fun", F.getName(), "");
+}
+
+bool SanitizerBlacklist::isIn(const llvm::GlobalVariable &G,
+                              const StringRef Category) const {
+  return isIn(*G.getParent(), Category) ||
+         SCL->inSection("global", G.getName(), Category) ||
+         SCL->inSection("type", GetGlobalTypeString(G), Category);
+}
diff --git a/lib/CodeGen/SanitizerBlacklist.h b/lib/CodeGen/SanitizerBlacklist.h
new file mode 100644
index 0000000..b8c283c
--- /dev/null
+++ b/lib/CodeGen/SanitizerBlacklist.h
@@ -0,0 +1,45 @@
+//===--- SanitizerBlacklist.h - Blacklist for sanitizers --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided blacklist used to disable/alter instrumentation done in
+// sanitizers.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_CODEGEN_SANITIZERBLACKLIST_H
+#define CLANG_CODEGEN_SANITIZERBLACKLIST_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace llvm {
+class GlobalVariable;
+class Function;
+class Module;
+}
+
+namespace clang {
+namespace CodeGen {
+
+class SanitizerBlacklist {
+  std::unique_ptr<llvm::SpecialCaseList> SCL;
+
+public:
+  SanitizerBlacklist(llvm::SpecialCaseList *SCL) : SCL(SCL) {}
+  bool isIn(const llvm::Module &M,
+            const StringRef Category = StringRef()) const;
+  bool isIn(const llvm::Function &F) const;
+  bool isIn(const llvm::GlobalVariable &G,
+            const StringRef Category = StringRef()) const;
+};
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index ab4c388..9cb93ac 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -957,8 +957,16 @@
   else
     State.FreeRegs = DefaultNumRegisterParameters;
 
-  if (!getCXXABI().classifyReturnType(FI))
+  if (!getCXXABI().classifyReturnType(FI)) {
     FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State);
+  } else if (FI.getReturnInfo().isIndirect()) {
+    // The C++ ABI is not aware of register usage, so we have to check if the
+    // return value was sret and put it in a register ourselves if appropriate.
+    if (State.FreeRegs) {
+      --State.FreeRegs;  // The sret parameter consumes a register.
+      FI.getReturnInfo().setInReg(true);
+    }
+  }
 
   bool UsedInAlloca = false;
   for (auto &I : FI.arguments()) {
@@ -1082,6 +1090,44 @@
   return AddrTyped;
 }
 
+bool X86_32TargetCodeGenInfo::isStructReturnInRegABI(
+    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
+  assert(Triple.getArch() == llvm::Triple::x86);
+
+  switch (Opts.getStructReturnConvention()) {
+  case CodeGenOptions::SRCK_Default:
+    break;
+  case CodeGenOptions::SRCK_OnStack:  // -fpcc-struct-return
+    return false;
+  case CodeGenOptions::SRCK_InRegs:  // -freg-struct-return
+    return true;
+  }
+
+  if (Triple.isOSDarwin())
+    return true;
+
+  switch (Triple.getOS()) {
+  case llvm::Triple::AuroraUX:
+  case llvm::Triple::DragonFly:
+  case llvm::Triple::FreeBSD:
+  case llvm::Triple::OpenBSD:
+  case llvm::Triple::Bitrig:
+    return true;
+  case llvm::Triple::Win32:
+    switch (Triple.getEnvironment()) {
+    case llvm::Triple::UnknownEnvironment:
+    case llvm::Triple::Cygnus:
+    case llvm::Triple::GNU:
+    case llvm::Triple::MSVC:
+      return true;
+    default:
+      return false;
+    }
+  default:
+    return false;
+  }
+}
+
 void X86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
                                                   llvm::GlobalValue *GV,
                                             CodeGen::CodeGenModule &CGM) const {
@@ -2045,7 +2091,7 @@
 /// the source type.  IROffset is an offset in bytes into the LLVM IR type that
 /// the 8-byte value references.  PrefType may be null.
 ///
-/// SourceTy is the source level type for the entire argument.  SourceOffset is
+/// SourceTy is the source-level type for the entire argument.  SourceOffset is
 /// an offset into this that we're processing (which is always either 0 or 8).
 ///
 llvm::Type *X86_64ABIInfo::
@@ -2590,8 +2636,8 @@
     llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi);
     llvm::Value *GPAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset);
     llvm::Value *FPAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);
-    llvm::Value *RegLoAddr = TyLo->isFloatingPointTy() ? FPAddr : GPAddr;
-    llvm::Value *RegHiAddr = TyLo->isFloatingPointTy() ? GPAddr : FPAddr;
+    llvm::Value *RegLoAddr = TyLo->isFPOrFPVectorTy() ? FPAddr : GPAddr;
+    llvm::Value *RegHiAddr = TyLo->isFPOrFPVectorTy() ? GPAddr : FPAddr;
     llvm::Value *V =
       CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegLoAddr, PTyLo));
     CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0));
@@ -2857,6 +2903,7 @@
   PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
 
   bool isPromotableTypeForABI(QualType Ty) const;
+  bool isAlignedParamType(QualType Ty) const;
 
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType Ty) const;
@@ -2877,7 +2924,8 @@
       const Type *T = isSingleElementStruct(I.type, getContext());
       if (T) {
         const BuiltinType *BT = T->getAs<BuiltinType>();
-        if (T->isVectorType() || (BT && BT->isFloatingPoint())) {
+        if ((T->isVectorType() && getContext().getTypeSize(T) == 128) ||
+            (BT && BT->isFloatingPoint())) {
           QualType QT(T, 0);
           I.info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT));
           continue;
@@ -2946,16 +2994,68 @@
   return false;
 }
 
+/// isAlignedParamType - Determine whether a type requires 16-byte
+/// alignment in the parameter area.
+bool
+PPC64_SVR4_ABIInfo::isAlignedParamType(QualType Ty) const {
+  // Complex types are passed just like their elements.
+  if (const ComplexType *CTy = Ty->getAs<ComplexType>())
+    Ty = CTy->getElementType();
+
+  // Only vector types of size 16 bytes need alignment (larger types are
+  // passed via reference, smaller types are not aligned).
+  if (Ty->isVectorType())
+    return getContext().getTypeSize(Ty) == 128;
+
+  // For single-element float/vector structs, we consider the whole type
+  // to have the same alignment requirements as its single element.
+  const Type *AlignAsType = nullptr;
+  const Type *EltType = isSingleElementStruct(Ty, getContext());
+  if (EltType) {
+    const BuiltinType *BT = EltType->getAs<BuiltinType>();
+    if ((EltType->isVectorType() &&
+         getContext().getTypeSize(EltType) == 128) ||
+        (BT && BT->isFloatingPoint()))
+      AlignAsType = EltType;
+  }
+
+  // With special case aggregates, only vector base types need alignment.
+  if (AlignAsType)
+    return AlignAsType->isVectorType();
+
+  // Otherwise, we only need alignment for any aggregate type that
+  // has an alignment requirement of >= 16 bytes.
+  if (isAggregateTypeForABI(Ty) && getContext().getTypeAlign(Ty) >= 128)
+    return true;
+
+  return false;
+}
+
 ABIArgInfo
 PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {
   if (Ty->isAnyComplexType())
     return ABIArgInfo::getDirect();
 
+  // Non-Altivec vector types are passed in GPRs (smaller than 16 bytes)
+  // or via reference (larger than 16 bytes).
+  if (Ty->isVectorType()) {
+    uint64_t Size = getContext().getTypeSize(Ty);
+    if (Size > 128)
+      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+    else if (Size < 128) {
+      llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size);
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+  }
+
   if (isAggregateTypeForABI(Ty)) {
     if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
       return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
 
-    return ABIArgInfo::getIndirect(0);
+    uint64_t ABIAlign = isAlignedParamType(Ty)? 16 : 8;
+    uint64_t TyAlign = getContext().getTypeAlign(Ty) / 8;
+    return ABIArgInfo::getIndirect(ABIAlign, /*ByVal=*/true,
+                                   /*Realign=*/TyAlign > ABIAlign);
   }
 
   return (isPromotableTypeForABI(Ty) ?
@@ -2970,6 +3070,18 @@
   if (RetTy->isAnyComplexType())
     return ABIArgInfo::getDirect();
 
+  // Non-Altivec vector types are returned in GPRs (smaller than 16 bytes)
+  // or via reference (larger than 16 bytes).
+  if (RetTy->isVectorType()) {
+    uint64_t Size = getContext().getTypeSize(RetTy);
+    if (Size > 128)
+      return ABIArgInfo::getIndirect(0);
+    else if (Size < 128) {
+      llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size);
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+  }
+
   if (isAggregateTypeForABI(RetTy))
     return ABIArgInfo::getIndirect(0);
 
@@ -2988,6 +3100,14 @@
   llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap");
   llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
 
+  // Handle types that require 16-byte alignment in the parameter save area.
+  if (isAlignedParamType(Ty)) {
+    llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int64Ty);
+    AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt64(15));
+    AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt64(-16));
+    Addr = Builder.CreateIntToPtr(AddrAsInt, BP, "ap.align");
+  }
+
   // Update the va_list pointer.  The pointer should be bumped by the
   // size of the object.  We can trust getTypeSize() except for a complex
   // type whose base type is smaller than a doubleword.  For these, the
@@ -3018,8 +3138,12 @@
   if (CplxBaseSize && CplxBaseSize < 8) {
     llvm::Value *RealAddr = Builder.CreatePtrToInt(Addr, CGF.Int64Ty);
     llvm::Value *ImagAddr = RealAddr;
-    RealAddr = Builder.CreateAdd(RealAddr, Builder.getInt64(8 - CplxBaseSize));
-    ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(16 - CplxBaseSize));
+    if (CGF.CGM.getDataLayout().isBigEndian()) {
+      RealAddr = Builder.CreateAdd(RealAddr, Builder.getInt64(8 - CplxBaseSize));
+      ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(16 - CplxBaseSize));
+    } else {
+      ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(8));
+    }
     llvm::Type *PBaseTy = llvm::PointerType::getUnqual(CGF.ConvertType(BaseTy));
     RealAddr = Builder.CreateIntToPtr(RealAddr, PBaseTy);
     ImagAddr = Builder.CreateIntToPtr(ImagAddr, PBaseTy);
@@ -3037,7 +3161,7 @@
   // If the argument is smaller than 8 bytes, it is right-adjusted in
   // its doubleword slot.  Adjust the pointer to pick it up from the
   // correct offset.
-  if (SizeInBytes < 8) {
+  if (SizeInBytes < 8 && CGF.CGM.getDataLayout().isBigEndian()) {
     llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int64Ty);
     AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt64(8 - SizeInBytes));
     Addr = Builder.CreateIntToPtr(AddrAsInt, BP);
@@ -4050,7 +4174,7 @@
 /// which have been allocated. It is valid for AllocatedGPRs to go above 4,
 /// this represents arguments being stored on the stack.
 void ARMABIInfo::markAllocatedGPRs(unsigned Alignment,
-                                          unsigned NumRequired) const {
+                                   unsigned NumRequired) const {
   assert((Alignment == 1 || Alignment == 2) && "Alignment must be 4 or 8 bytes");
 
   if (Alignment == 2 && AllocatedGPRs & 0x1)
@@ -4193,8 +4317,11 @@
       getABIKind() == ARMABIInfo::AAPCS)
     ABIAlign = std::min(std::max(TyAlign, (uint64_t)4), (uint64_t)8);
   if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) {
-    // Update Allocated GPRs
-    markAllocatedGPRs(1, 1);
+    // Update Allocated GPRs. Since this is only used when the size of the
+    // argument is greater than 64 bytes, this will always use up any available
+    // registers (of which there are 4). We also don't care about getting the
+    // alignment right, because general-purpose registers cannot be back-filled.
+    markAllocatedGPRs(1, 4);
     return ABIArgInfo::getIndirect(TyAlign, /*ByVal=*/true,
            /*Realign=*/TyAlign > ABIAlign);
   }
@@ -4372,6 +4499,10 @@
   // are returned indirectly.
   uint64_t Size = getContext().getTypeSize(RetTy);
   if (Size <= 32) {
+    if (getDataLayout().isBigEndian())
+      // Return in 32 bit integer integer type (as if loaded by LDR, AAPCS 5.4)
+      return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
+
     // Return in the smallest viable integer type.
     if (Size <= 8)
       return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
@@ -4876,44 +5007,6 @@
   return ResAddr;
 }
 
-bool X86_32TargetCodeGenInfo::isStructReturnInRegABI(
-    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
-  assert(Triple.getArch() == llvm::Triple::x86);
-
-  switch (Opts.getStructReturnConvention()) {
-  case CodeGenOptions::SRCK_Default:
-    break;
-  case CodeGenOptions::SRCK_OnStack:  // -fpcc-struct-return
-    return false;
-  case CodeGenOptions::SRCK_InRegs:  // -freg-struct-return
-    return true;
-  }
-
-  if (Triple.isOSDarwin())
-    return true;
-
-  switch (Triple.getOS()) {
-  case llvm::Triple::AuroraUX:
-  case llvm::Triple::DragonFly:
-  case llvm::Triple::FreeBSD:
-  case llvm::Triple::OpenBSD:
-  case llvm::Triple::Bitrig:
-    return true;
-  case llvm::Triple::Win32:
-    switch (Triple.getEnvironment()) {
-    case llvm::Triple::UnknownEnvironment:
-    case llvm::Triple::Cygnus:
-    case llvm::Triple::GNU:
-    case llvm::Triple::MSVC:
-      return true;
-    default:
-      return false;
-    }
-  default:
-    return false;
-  }
-}
-
 ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
@@ -6332,7 +6425,8 @@
 }
 
 /// Appends array encoding to Enc before calling appendType for the element.
-static bool appendArrayType(SmallStringEnc &Enc, const ArrayType *AT,
+static bool appendArrayType(SmallStringEnc &Enc, QualType QT,
+                            const ArrayType *AT,
                             const CodeGen::CodeGenModule &CGM,
                             TypeStringCache &TSC, StringRef NoSizeEnc) {
   if (AT->getSizeModifier() != ArrayType::Normal)
@@ -6343,6 +6437,8 @@
   else
     Enc += NoSizeEnc; // Global arrays use "*", otherwise it is "".
   Enc += ':';
+  // The Qualifiers should be attached to the type rather than the array.
+  appendQualifier(Enc, QT);
   if (!appendType(Enc, AT->getElementType(), CGM, TSC))
     return false;
   Enc += ')';
@@ -6391,14 +6487,16 @@
 
   QualType QT = QType.getCanonicalType();
 
+  if (const ArrayType *AT = QT->getAsArrayTypeUnsafe())
+    // The Qualifiers should be attached to the type rather than the array.
+    // Thus we don't call appendQualifier() here.
+    return appendArrayType(Enc, QT, AT, CGM, TSC, "");
+
   appendQualifier(Enc, QT);
 
   if (const BuiltinType *BT = QT->getAs<BuiltinType>())
     return appendBuiltinType(Enc, BT);
 
-  if (const ArrayType *AT = QT->getAsArrayTypeUnsafe())
-    return appendArrayType(Enc, AT, CGM, TSC, "");
-
   if (const PointerType *PT = QT->getAs<PointerType>())
     return appendPointerType(Enc, PT, CGM, TSC);
 
@@ -6434,8 +6532,9 @@
     QualType QT = VD->getType().getCanonicalType();
     if (const ArrayType *AT = QT->getAsArrayTypeUnsafe()) {
       // Global ArrayTypes are given a size of '*' if the size is unknown.
-      appendQualifier(Enc, QT);
-      return appendArrayType(Enc, AT, CGM, TSC, "*");
+      // The Qualifiers should be attached to the type rather than the array.
+      // Thus we don't call appendQualifier() here.
+      return appendArrayType(Enc, QT, AT, CGM, TSC, "*");
     }
     return appendType(Enc, QT, CGM, TSC);
   }
@@ -6471,7 +6570,7 @@
   case llvm::Triple::arm64:
   case llvm::Triple::arm64_be: {
     AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS;
-    if (strcmp(getTarget().getABI(), "darwinpcs") == 0)
+    if (getTarget().getABI() == "darwinpcs")
       Kind = AArch64ABIInfo::DarwinPCS;
 
     return *(TheTargetCodeGenInfo = new AArch64TargetCodeGenInfo(Types, Kind));
@@ -6483,7 +6582,7 @@
   case llvm::Triple::thumbeb:
     {
       ARMABIInfo::ABIKind Kind = ARMABIInfo::AAPCS;
-      if (strcmp(getTarget().getABI(), "apcs-gnu") == 0)
+      if (getTarget().getABI() == "apcs-gnu")
         Kind = ARMABIInfo::APCS;
       else if (CodeGenOpts.FloatABI == "hard" ||
                (CodeGenOpts.FloatABI != "soft" &&
@@ -6546,7 +6645,7 @@
   }
 
   case llvm::Triple::x86_64: {
-    bool HasAVX = strcmp(getTarget().getABI(), "avx") == 0;
+    bool HasAVX = getTarget().getABI() == "avx";
 
     switch (Triple.getOS()) {
     case llvm::Triple::Win32:
diff --git a/lib/Driver/Android.mk b/lib/Driver/Android.mk
index 559ca83..a80df60 100644
--- a/lib/Driver/Android.mk
+++ b/lib/Driver/Android.mk
@@ -11,12 +11,10 @@
   DiagnosticDriverKinds.inc \
   DiagnosticSemaKinds.inc \
   Options.inc \
-  CC1Options.inc \
-  CC1AsOptions.inc
+  CC1Options.inc
 
 clang_driver_SRC_FILES := \
   Action.cpp \
-  CC1AsOptions.cpp \
   Compilation.cpp \
   Driver.cpp \
   DriverOptions.cpp \
diff --git a/lib/Driver/CC1AsOptions.cpp b/lib/Driver/CC1AsOptions.cpp
deleted file mode 100644
index 22180c9..0000000
--- a/lib/Driver/CC1AsOptions.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- CC1AsOptions.cpp - Clang Assembler Options Table -----------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Driver/CC1AsOptions.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Option/OptTable.h"
-#include "llvm/Option/Option.h"
-using namespace clang;
-using namespace clang::driver;
-using namespace llvm::opt;
-using namespace clang::driver::cc1asoptions;
-
-#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
-#include "clang/Driver/CC1AsOptions.inc"
-#undef PREFIX
-
-static const OptTable::Info CC1AsInfoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
-               HELPTEXT, METAVAR)   \
-  { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
-    FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
-#include "clang/Driver/CC1AsOptions.inc"
-#undef OPTION
-};
-
-namespace {
-
-class CC1AsOptTable : public OptTable {
-public:
-  CC1AsOptTable()
-    : OptTable(CC1AsInfoTable, llvm::array_lengthof(CC1AsInfoTable)) {}
-};
-
-}
-
-OptTable *clang::driver::createCC1AsOptTable() {
-  return new CC1AsOptTable();
-}
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index f2bdaee..33db5e9 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -1,12 +1,10 @@
 set(LLVM_LINK_COMPONENTS
   Option
   Support
-  TransformUtils
   )
 
 add_clang_library(clangDriver
   Action.cpp
-  CC1AsOptions.cpp
   Compilation.cpp
   Driver.cpp
   DriverOptions.cpp
@@ -22,7 +20,6 @@
   Types.cpp
 
   DEPENDS
-  ClangCC1AsOptions
   ClangDriverOptions
 
   LINK_LIBS
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 8ec643c..49b7edd 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -17,8 +17,6 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_ostream.h"
-#include <errno.h>
-#include <sys/stat.h>
 
 using namespace clang::driver;
 using namespace clang;
@@ -26,9 +24,9 @@
 
 Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
                          InputArgList *_Args, DerivedArgList *_TranslatedArgs)
-  : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
-    TranslatedArgs(_TranslatedArgs), Redirects(nullptr) {
-}
+    : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
+      TranslatedArgs(_TranslatedArgs), Redirects(nullptr),
+      ForDiagnostics(false) {}
 
 Compilation::~Compilation() {
   delete TranslatedArgs;
@@ -86,7 +84,7 @@
   if (!llvm::sys::fs::can_write(File) || !llvm::sys::fs::is_regular_file(File))
     return true;
 
-  if (llvm::error_code EC = llvm::sys::fs::remove(File)) {
+  if (std::error_code EC = llvm::sys::fs::remove(File)) {
     // Failure is only failure if the file exists and is "regular". We checked
     // for it being regular before, and llvm::sys::fs::remove ignores ENOENT,
     // so we don't need to check again.
@@ -211,6 +209,8 @@
 }
 
 void Compilation::initCompilationForDiagnostics() {
+  ForDiagnostics = true;
+
   // Free actions and jobs.
   DeleteContainerPointers(Actions);
   Jobs.clear();
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index a0fcf41..2844033 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -11,6 +11,7 @@
 #include "InputInfo.h"
 #include "ToolChains.h"
 #include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
 #include "clang/Driver/Action.h"
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/DriverDiagnostic.h"
@@ -20,6 +21,7 @@
 #include "clang/Driver/ToolChain.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Option/Arg.h"
@@ -32,15 +34,12 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
 #include <map>
 #include <memory>
 
-// FIXME: It would prevent us from including llvm-config.h
-// if config.h were included before system_error.h.
-#include "clang/Config/config.h"
-
 using namespace clang::driver;
 using namespace clang;
 using namespace llvm::opt;
@@ -155,9 +154,10 @@
   Arg *PhaseArg = nullptr;
   phases::ID FinalPhase;
 
-  // -{E,M,MM} and /P only run the preprocessor.
+  // -{E,EP,P,M,MM} only run the preprocessor.
   if (CCCIsCPP() ||
       (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
+      (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
       (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
       (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
     FinalPhase = phases::Preprocess;
@@ -419,8 +419,6 @@
   // Suppress driver output and emit preprocessor output to temp file.
   Mode = CPPMode;
   CCGenDiagnostics = true;
-  C.getArgs().AddFlagArg(nullptr,
-                         Opts->getOption(options::OPT_frewrite_includes));
 
   // Save the original job command(s).
   std::string Cmd;
@@ -521,16 +519,25 @@
     for (ArgStringList::const_iterator it = Files.begin(), ie = Files.end();
          it != ie; ++it) {
       Diag(clang::diag::note_drv_command_failed_diag_msg) << *it;
+      std::string Script = StringRef(*it).rsplit('.').first;
+      // In some cases (modules) we'll dump extra data to help with reproducing
+      // the crash into a directory next to the output.
+      SmallString<128> VFS;
+      if (llvm::sys::fs::exists(Script + ".cache")) {
+        Diag(clang::diag::note_drv_command_failed_diag_msg)
+            << Script + ".cache";
+        VFS = llvm::sys::path::filename(Script + ".cache");
+        llvm::sys::path::append(VFS, "vfs", "vfs.yaml");
+      }
 
       std::string Err;
-      std::string Script = StringRef(*it).rsplit('.').first;
       Script += ".sh";
       llvm::raw_fd_ostream ScriptOS(Script.c_str(), Err, llvm::sys::fs::F_Excl);
       if (!Err.empty()) {
         Diag(clang::diag::note_drv_command_failed_diag_msg)
           << "Error generating run script: " + Script + " " + Err;
       } else {
-        // Append the new filename with correct preprocessed suffix.
+        // Replace the original filename with the preprocessed one.
         size_t I, E;
         I = Cmd.find("-main-file-name ");
         assert (I != std::string::npos && "Expected to find -main-file-name");
@@ -543,6 +550,11 @@
         E = I + OldFilename.size();
         I = Cmd.rfind(" ", I) + 1;
         Cmd.replace(I, E - I, NewFilename.data(), NewFilename.size());
+        if (!VFS.empty()) {
+          // Add the VFS overlay to the reproduction script.
+          I += NewFilename.size();
+          Cmd.insert(I, std::string(" -ivfsoverlay ") + VFS.c_str());
+        }
         ScriptOS << Cmd;
         Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
       }
@@ -600,7 +612,7 @@
     // Print extra information about abnormal failures, if possible.
     //
     // This is ad-hoc, but we don't want to be excessively noisy. If the result
-    // status was 1, assume the command failed normally. In particular, if it 
+    // status was 1, assume the command failed normally. In particular, if it
     // was the compiler then assume it gave a reasonable error code. Failures
     // in other tools are less common, and they generally have worse
     // diagnostics, so always print the diagnostic there.
@@ -952,6 +964,9 @@
   if (llvm::sys::fs::exists(Twine(Path)))
     return true;
 
+  if (D.IsCLMode() && llvm::sys::Process::FindInEnvPath("LIB", Value))
+    return true;
+
   D.Diag(clang::diag::err_drv_no_such_file) << Path.str();
   return false;
 }
@@ -1268,7 +1283,8 @@
     } else {
       OutputTy = Input->getType();
       if (!Args.hasFlag(options::OPT_frewrite_includes,
-                        options::OPT_fno_rewrite_includes, false))
+                        options::OPT_fno_rewrite_includes, false) &&
+          !CCGenDiagnostics)
         OutputTy = types::getPreprocessedType(OutputTy);
       assert(OutputTy != types::TY_INVALID &&
              "Cannot preprocess this input type!");
@@ -1574,7 +1590,7 @@
 static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue,
                                         StringRef BaseName, types::ID FileType) {
   SmallString<128> Filename = ArgValue;
-  
+
   if (ArgValue.empty()) {
     // If the argument is empty, output to BaseName in the current dir.
     Filename = BaseName;
@@ -1617,7 +1633,10 @@
   if (C.getArgs().hasArg(options::OPT__SLASH_P)) {
     assert(AtTopLevel && isa<PreprocessJobAction>(JA));
     StringRef BaseName = llvm::sys::path::filename(BaseInput);
-    return C.addResultFile(MakeCLOutputFilename(C.getArgs(), "", BaseName,
+    StringRef NameArg;
+    if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi))
+      NameArg = A->getValue();
+    return C.addResultFile(MakeCLOutputFilename(C.getArgs(), NameArg, BaseName,
                                                 types::TY_PP_C), &JA);
   }
 
@@ -1826,8 +1845,7 @@
 std::string Driver::GetTemporaryPath(StringRef Prefix, const char *Suffix)
   const {
   SmallString<128> Path;
-  llvm::error_code EC =
-      llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
+  std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
   if (EC) {
     Diag(clang::diag::err_unable_to_make_temp) << EC.message();
     return "";
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 38f68eb..42cc1bc 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -41,7 +41,7 @@
     .Cases("-internal-externc-isystem", "-iprefix", "-iwithprefix", true)
     .Cases("-iwithprefixbefore", "-isysroot", "-isystem", "-iquote", true)
     .Cases("-resource-dir", "-serialize-diagnostic-file", true)
-    .Case("-dwarf-debug-flags", true)
+    .Cases("-dwarf-debug-flags", "-ivfsoverlay", true)
     .Default(false);
 
   // Match found.
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index c336195..b64f027 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -15,7 +15,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Transforms/Utils/SpecialCaseList.h"
+#include "llvm/Support/SpecialCaseList.h"
 #include <memory>
 
 using namespace clang::driver;
@@ -113,14 +113,6 @@
   // -f(-no)sanitize=leak should change whether leak detection is enabled by
   // default in ASan?
 
-  // If -fsanitize contains extra features of ASan, it should also
-  // explicitly contain -fsanitize=address (probably, turned off later in the
-  // command line).
-  if ((Kind & AddressFull) != 0 && (AllAdd & Address) == 0)
-    D.Diag(diag::warn_drv_unused_sanitizer)
-     << lastArgumentForKind(D, Args, AddressFull)
-     << "-fsanitize=address";
-
   // Parse -f(no-)sanitize-blacklist options.
   if (Arg *BLArg = Args.getLastArg(options::OPT_fsanitize_blacklist,
                                    options::OPT_fno_sanitize_blacklist)) {
@@ -171,8 +163,8 @@
 
   if (NeedsAsan) {
     AsanSharedRuntime =
-      (TC.getTriple().getEnvironment() == llvm::Triple::Android) ||
-      Args.hasArg(options::OPT_shared_libasan);
+        Args.hasArg(options::OPT_shared_libasan) ||
+        (TC.getTriple().getEnvironment() == llvm::Triple::Android);
     AsanZeroBaseShadow =
         (TC.getTriple().getEnvironment() == llvm::Triple::Android);
   }
@@ -210,11 +202,6 @@
 #define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID##Group)
 #include "clang/Basic/Sanitizers.def"
     .Default(SanitizeKind());
-  // Assume -fsanitize=address implies -fsanitize=init-order,use-after-return.
-  // FIXME: This should be either specified in Sanitizers.def, or go away when
-  // we get rid of "-fsanitize=init-order,use-after-return" flags at all.
-  if (ParsedKind & Address)
-    ParsedKind |= InitOrder | UseAfterReturn;
   return ParsedKind;
 }
 
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index eefe487..4f90d08 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -15,6 +15,7 @@
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -147,6 +148,30 @@
   return D.GetProgramPath(Name, *this);
 }
 
+std::string ToolChain::GetLinkerPath() const {
+  if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
+    StringRef Suffix = A->getValue();
+
+    // If we're passed -fuse-ld= with no argument, or with the argument ld,
+    // then use whatever the default system linker is.
+    if (Suffix.empty() || Suffix == "ld")
+      return GetProgramPath("ld");
+
+    llvm::SmallString<8> LinkerName("ld.");
+    LinkerName.append(Suffix);
+
+    std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
+    if (llvm::sys::fs::exists(LinkerPath))
+      return LinkerPath;
+
+    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
+    return "";
+  }
+
+  return GetProgramPath("ld");
+}
+
+
 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
   return types::lookupTypeForExtension(Ext);
 }
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 8d8e7c7..2d8669b 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -10,6 +10,7 @@
 #include "ToolChains.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/Version.h"
+#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
@@ -29,13 +30,8 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
-
-// FIXME: This needs to be listed last until we fix the broken include guards
-// in these files and the LLVM config.h files.
-#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
-
 #include <cstdlib> // ::getenv
+#include <system_error>
 
 using namespace clang::driver;
 using namespace clang::driver::toolchains;
@@ -1345,8 +1341,9 @@
     "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu",
     "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux",
     "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux",
-    "x86_64-linux-android"
+    "x86_64-linux-android", "x86_64-unknown-linux"
   };
+  static const char *const X32LibDirs[] = { "/libx32" };
   static const char *const X86LibDirs[] = { "/lib32", "/lib" };
   static const char *const X86Triples[] = {
     "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", "i386-linux-gnu",
@@ -1357,18 +1354,24 @@
 
   static const char *const MIPSLibDirs[] = { "/lib" };
   static const char *const MIPSTriples[] = { "mips-linux-gnu",
-                                             "mips-mti-linux-gnu" };
+                                             "mips-mti-linux-gnu",
+                                             "mips-img-linux-gnu" };
   static const char *const MIPSELLibDirs[] = { "/lib" };
   static const char *const MIPSELTriples[] = { "mipsel-linux-gnu",
-                                               "mipsel-linux-android" };
+                                               "mipsel-linux-android",
+                                               "mips-img-linux-gnu" };
 
   static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
   static const char *const MIPS64Triples[] = { "mips64-linux-gnu",
-                                               "mips-mti-linux-gnu" };
+                                               "mips-mti-linux-gnu",
+                                               "mips-img-linux-gnu",
+                                               "mips64-linux-gnuabi64" };
   static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
   static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu",
                                                  "mips-mti-linux-gnu",
-                                                 "mips64el-linux-android" };
+                                                 "mips-img-linux-gnu",
+                                                 "mips64el-linux-android",
+                                                 "mips64el-linux-gnuabi64" };
 
   static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
   static const char *const PPCTriples[] = {
@@ -1449,10 +1452,19 @@
                    X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
     TripleAliases.append(X86_64Triples,
                          X86_64Triples + llvm::array_lengthof(X86_64Triples));
-    BiarchLibDirs.append(X86LibDirs,
-                         X86LibDirs + llvm::array_lengthof(X86LibDirs));
-    BiarchTripleAliases.append(X86Triples,
-                               X86Triples + llvm::array_lengthof(X86Triples));
+    // x32 is always available when x86_64 is available, so adding it as secondary
+    // arch with x86_64 triples
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) {
+      BiarchLibDirs.append(X32LibDirs,
+                           X32LibDirs + llvm::array_lengthof(X32LibDirs));
+      BiarchTripleAliases.append(X86_64Triples,
+                                 X86_64Triples + llvm::array_lengthof(X86_64Triples));
+    } else {
+      BiarchLibDirs.append(X86LibDirs,
+                           X86LibDirs + llvm::array_lengthof(X86LibDirs));
+      BiarchTripleAliases.append(X86Triples,
+                                 X86Triples + llvm::array_lengthof(X86Triples));
+    }
     break;
   case llvm::Triple::x86:
     LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
@@ -1635,7 +1647,8 @@
   Arg *A = Args.getLastArg(options::OPT_march_EQ,
                            options::OPT_mcpu_EQ);
 
-  return A && A->getValue() == StringRef("mips64r2");
+  return A && (A->getValue() == StringRef("mips64r2") ||
+               A->getValue() == StringRef("octeon"));
 }
 
 static bool isMicroMips(const ArgList &Args) {
@@ -1870,6 +1883,33 @@
       .FilterOut(NonExistent);
   }
 
+  MultilibSet ImgMultilibs;
+  {
+    Multilib Mips64r6 = Multilib()
+      .gccSuffix("/mips64r6")
+      .osSuffix("/mips64r6")
+      .includeSuffix("/mips64r6")
+      .flag("+m64").flag("-m32");
+
+    Multilib LittleEndian = Multilib()
+      .gccSuffix("/el")
+      .osSuffix("/el")
+      .includeSuffix("/el")
+      .flag("+EL").flag("-EB");
+
+    Multilib MAbi64 = Multilib()
+      .gccSuffix("/64")
+      .osSuffix("/64")
+      .includeSuffix("/64")
+      .flag("+mabi=64").flag("-mabi=n32").flag("-m32");
+
+    ImgMultilibs = MultilibSet()
+      .Maybe(Mips64r6)
+      .Maybe(MAbi64)
+      .Maybe(LittleEndian)
+      .FilterOut(NonExistent);
+  }
+
   llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
 
   Multilib::flags_list Flags;
@@ -1904,6 +1944,17 @@
     return false;
   }
 
+  if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
+      TargetTriple.getOS() == llvm::Triple::Linux &&
+      TargetTriple.getEnvironment() == llvm::Triple::GNU) {
+    // Select mips-img-linux-gnu toolchain.
+    if (ImgMultilibs.select(Flags, Result.SelectedMultilib)) {
+      Result.Multilibs = ImgMultilibs;
+      return true;
+    }
+    return false;
+  }
+
   // Sort candidates. Toolchain that best meets the directories goes first.
   // Then select the first toolchains matches command line flags.
   MultilibSet *candidates[] = { &DebianMipsMultilibs, &FSFMipsMultilibs,
@@ -1920,6 +1971,18 @@
     }
   }
 
+  {
+    // Fallback to the regular toolchain-tree structure.
+    Multilib Default;
+    Result.Multilibs.push_back(Default);
+    Result.Multilibs.FilterOut(NonExistent);
+
+    if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) {
+      Result.BiarchSibling = Multilib();
+      return true;
+    }
+  }
+
   return false;
 }
 
@@ -1939,47 +2002,64 @@
   Multilib Alt64 = Multilib()
     .gccSuffix("/64")
     .includeSuffix("/64")
-    .flag("-m32").flag("+m64");
+    .flag("-m32").flag("+m64").flag("-mx32");
   Multilib Alt32 = Multilib()
     .gccSuffix("/32")
     .includeSuffix("/32")
-    .flag("+m32").flag("-m64");
+    .flag("+m32").flag("-m64").flag("-mx32");
+  Multilib Altx32 = Multilib()
+    .gccSuffix("/x32")
+    .includeSuffix("/x32")
+    .flag("-m32").flag("-m64").flag("+mx32");
 
   FilterNonExistent NonExistent(Path);
 
-  // Decide whether the default multilib is 32bit, correcting for
-  // when the default multilib and the alternate appear backwards
-  bool DefaultIs32Bit;
+  // Determine default multilib from: 32, 64, x32
+  // Also handle cases such as 64 on 32, 32 on 64, etc.
+  enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
+  const bool IsX32 {TargetTriple.getEnvironment() == llvm::Triple::GNUX32};
   if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
-    DefaultIs32Bit = false;
-  else if (TargetTriple.isArch64Bit() && !NonExistent(Alt64))
-    DefaultIs32Bit = true;
+    Want = WANT64;
+  else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
+    Want = WANT64;
+  else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
+    Want = WANT32;
   else {
-    if (NeedsBiarchSuffix)
-      DefaultIs32Bit = TargetTriple.isArch64Bit();
+    if (TargetTriple.isArch32Bit())
+      Want = NeedsBiarchSuffix ? WANT64 : WANT32;
+    else if (IsX32)
+      Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
     else
-      DefaultIs32Bit = TargetTriple.isArch32Bit();
+      Want = NeedsBiarchSuffix ? WANT32 : WANT64;
   }
 
-  if (DefaultIs32Bit)
-    Default.flag("+m32").flag("-m64");
+  if (Want == WANT32)
+    Default.flag("+m32").flag("-m64").flag("-mx32");
+  else if (Want == WANT64)
+    Default.flag("-m32").flag("+m64").flag("-mx32");
+  else if (Want == WANTX32)
+    Default.flag("-m32").flag("-m64").flag("+mx32");
   else
-    Default.flag("-m32").flag("+m64");
+    return false;
 
   Result.Multilibs.push_back(Default);
   Result.Multilibs.push_back(Alt64);
   Result.Multilibs.push_back(Alt32);
+  Result.Multilibs.push_back(Altx32);
 
   Result.Multilibs.FilterOut(NonExistent);
 
   Multilib::flags_list Flags;
-  addMultilibFlag(TargetTriple.isArch64Bit(), "m64", Flags);
+  addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags);
   addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
+  addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags);
 
   if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
     return false;
 
-  if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32)
+  if (Result.SelectedMultilib == Alt64 ||
+      Result.SelectedMultilib == Alt32 ||
+      Result.SelectedMultilib == Altx32)
     Result.BiarchSibling = Default;
 
   return true;
@@ -2021,7 +2101,7 @@
       (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86));
   for (unsigned i = 0; i < NumLibSuffixes; ++i) {
     StringRef LibSuffix = LibSuffixes[i];
-    llvm::error_code EC;
+    std::error_code EC;
     for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE;
          !EC && LI != LE; LI = LI.increment(EC)) {
       StringRef VersionText = llvm::sys::path::filename(LI->path());
@@ -2231,7 +2311,7 @@
 
   // Determine version of GCC libraries and headers to use.
   const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
-  llvm::error_code ec;
+  std::error_code ec;
   GCCVersion MaxVersion= GCCVersion::Parse("0.0.0");
   for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;
        !ec && di != de; di = di.increment(ec)) {
@@ -2783,8 +2863,9 @@
 }
 
 static Distro DetectDistro(llvm::Triple::ArchType Arch) {
-  std::unique_ptr<llvm::MemoryBuffer> File;
-  if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) {
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
+      llvm::MemoryBuffer::getFile("/etc/lsb-release");
+  if (File) {
     StringRef Data = File.get()->getBuffer();
     SmallVector<StringRef, 8> Lines;
     Data.split(Lines, "\n");
@@ -2809,7 +2890,8 @@
     return Version;
   }
 
-  if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
+  File = llvm::MemoryBuffer::getFile("/etc/redhat-release");
+  if (File) {
     StringRef Data = File.get()->getBuffer();
     if (Data.startswith("Fedora release"))
       return Fedora;
@@ -2825,7 +2907,8 @@
     return UnknownDistro;
   }
 
-  if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) {
+  File = llvm::MemoryBuffer::getFile("/etc/debian_version");
+  if (File) {
     StringRef Data = File.get()->getBuffer();
     if (Data[0] == '5')
       return DebianLenny;
@@ -2893,7 +2976,9 @@
       return "i386-linux-gnu";
     return TargetTriple.str();
   case llvm::Triple::x86_64:
-    if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
+    // We don't want this for x32, otherwise it will match x86_64 libs
+    if (TargetTriple.getEnvironment() != llvm::Triple::GNUX32 &&
+        llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
       return "x86_64-linux-gnu";
     return TargetTriple.str();
   case llvm::Triple::arm64:
@@ -2914,6 +2999,18 @@
     if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu"))
       return "mipsel-linux-gnu";
     return TargetTriple.str();
+  case llvm::Triple::mips64:
+    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnu"))
+      return "mips64-linux-gnu";
+    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
+      return "mips64-linux-gnuabi64";
+    return TargetTriple.str();
+  case llvm::Triple::mips64el:
+    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnu"))
+      return "mips64el-linux-gnu";
+    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
+      return "mips64el-linux-gnuabi64";
+    return TargetTriple.str();
   case llvm::Triple::ppc:
     if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
       return "powerpc-linux-gnuspe";
@@ -2957,6 +3054,10 @@
       Triple.getArch() == llvm::Triple::ppc)
     return "lib32";
 
+  if (Triple.getArch() == llvm::Triple::x86_64 &&
+      Triple.getEnvironment() == llvm::Triple::GNUX32)
+    return "libx32";
+
   return Triple.isArch32Bit() ? "lib" : "lib64";
 }
 
@@ -2979,7 +3080,7 @@
   PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
                          GCCInstallation.getTriple().str() + "/bin").str());
 
-  Linker = GetProgramPath("ld");
+  Linker = GetLinkerPath();
 
   Distro Distro = DetectDistro(Arch);
 
@@ -3262,12 +3363,23 @@
   const StringRef MIPSELMultiarchIncludeDirs[] = {
     "/usr/include/mipsel-linux-gnu"
   };
+  const StringRef MIPS64MultiarchIncludeDirs[] = {
+    "/usr/include/mips64-linux-gnu",
+    "/usr/include/mips64-linux-gnuabi64"
+  };
+  const StringRef MIPS64ELMultiarchIncludeDirs[] = {
+    "/usr/include/mips64el-linux-gnu",
+    "/usr/include/mips64el-linux-gnuabi64"
+  };
   const StringRef PPCMultiarchIncludeDirs[] = {
     "/usr/include/powerpc-linux-gnu"
   };
   const StringRef PPC64MultiarchIncludeDirs[] = {
     "/usr/include/powerpc64-linux-gnu"
   };
+  const StringRef PPC64LEMultiarchIncludeDirs[] = {
+    "/usr/include/powerpc64le-linux-gnu"
+  };
   ArrayRef<StringRef> MultiarchIncludeDirs;
   if (getTriple().getArch() == llvm::Triple::x86_64) {
     MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
@@ -3287,10 +3399,16 @@
     MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::mipsel) {
     MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
+  } else if (getTriple().getArch() == llvm::Triple::mips64) {
+    MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
+  } else if (getTriple().getArch() == llvm::Triple::mips64el) {
+    MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::ppc) {
     MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::ppc64) {
     MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
+  } else if (getTriple().getArch() == llvm::Triple::ppc64le) {
+    MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
   }
   for (StringRef Dir : MultiarchIncludeDirs) {
     if (llvm::sys::fs::exists(SysRoot + Dir)) {
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 13e9d67..8931aec 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -537,6 +537,12 @@
     return 2;
   }
 
+  virtual bool IsIntegratedAssemblerDefault() const {
+    if (getTriple().getArch() == llvm::Triple::ppc)
+      return true;
+    return Generic_ELF::IsIntegratedAssemblerDefault();
+  }
+
 protected:
   Tool *buildAssembler() const override;
   Tool *buildLinker() const override;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 76b7962..e3532aa 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -38,7 +38,6 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
-#include <sys/stat.h>
 
 using namespace clang::driver;
 using namespace clang::driver::tools;
@@ -63,10 +62,14 @@
 /// CheckPreprocessingOptions - Perform some validation of preprocessing
 /// arguments that is shared with gcc.
 static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
-    if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP())
+  if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) {
+    if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
+        !Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
       D.Diag(diag::err_drv_argument_only_allowed_with)
-        << A->getAsString(Args) << "-E";
+          << A->getBaseArg().getAsString(Args)
+          << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
+    }
+  }
 }
 
 /// CheckCodeGenerationOptions - Perform some validation of code generation
@@ -173,10 +176,7 @@
   // (constructed via -Xarch_).
   Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
-
+  for (const auto &II : Inputs) {
     if (!TC.HasNativeLLVMSupport()) {
       // Don't try to pass LLVM inputs unless we have native support.
       if (II.getType() == types::TY_LLVM_IR ||
@@ -197,11 +197,11 @@
     const Arg &A = II.getInputArg();
 
     // Handle reserved library options.
-    if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
+    if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
       TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-    } else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) {
+    else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
       TC.AddCCKextLibArgs(Args, CmdArgs);
-    } else
+    else
       A.renderAsInput(Args, CmdArgs);
   }
 
@@ -897,6 +897,14 @@
     CmdArgs.push_back("-backend-option");
     CmdArgs.push_back("-aarch64-strict-align");
   }
+
+  // Setting -mno-global-merge disables the codegen global merge pass. Setting
+  // -mglobal-merge has no effect as the pass is enabled by default.
+  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
+                               options::OPT_mno_global_merge)) {
+    if (A->getOption().matches(options::OPT_mno_global_merge))
+      CmdArgs.push_back("-mno-global-merge");
+  }
 }
 
 // Get CPU and ABI names. They are not independent
@@ -908,6 +916,14 @@
   const char *DefMips32CPU = "mips32r2";
   const char *DefMips64CPU = "mips64r2";
 
+  // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
+  // default for mips64(el)?-img-linux-gnu.
+  if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
+      Triple.getEnvironment() == llvm::Triple::GNU) {
+    DefMips32CPU = "mips32r6";
+    DefMips64CPU = "mips64r6";
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
                                options::OPT_mcpu_EQ))
     CPUName = A->getValue();
@@ -938,22 +954,22 @@
     }
   }
 
-  if (!ABIName.empty()) {
-    // Deduce CPU name from ABI name.
-    CPUName = llvm::StringSwitch<const char *>(ABIName)
-      .Cases("32", "o32", "eabi", DefMips32CPU)
-      .Cases("n32", "n64", "64", DefMips64CPU)
-      .Default("");
-  }
-  else if (!CPUName.empty()) {
-    // Deduce ABI name from CPU name.
-    ABIName = llvm::StringSwitch<const char *>(CPUName)
-      .Cases("mips32", "mips32r2", "o32")
-      .Cases("mips64", "mips64r2", "n64")
-      .Default("");
+  if (ABIName.empty()) {
+    // Deduce ABI name from the target triple.
+    if (Triple.getArch() == llvm::Triple::mips ||
+        Triple.getArch() == llvm::Triple::mipsel)
+      ABIName = "o32";
+    else
+      ABIName = "n64";
   }
 
-  // FIXME: Warn on inconsistent cpu and abi usage.
+  if (CPUName.empty()) {
+    // Deduce CPU name from ABI name.
+    CPUName = llvm::StringSwitch<const char *>(ABIName)
+      .Cases("o32", "eabi", DefMips32CPU)
+      .Cases("n32", "n64", DefMips64CPU)
+      .Default("");
+  }
 }
 
 // Convert ABI name to the GNU tools acceptable variant.
@@ -1042,6 +1058,8 @@
                    "msa");
   AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32,
                    "fp64");
+  AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
+                   options::OPT_modd_spreg, "nooddspreg");
 }
 
 void Clang::AddMIPSTargetArgs(const ArgList &Args,
@@ -1147,6 +1165,7 @@
       .Case("power6", "pwr6")
       .Case("power6x", "pwr6x")
       .Case("power7", "pwr7")
+      .Case("power8", "pwr8")
       .Case("pwr3", "pwr3")
       .Case("pwr4", "pwr4")
       .Case("pwr5", "pwr5")
@@ -1154,6 +1173,7 @@
       .Case("pwr6", "pwr6")
       .Case("pwr6x", "pwr6x")
       .Case("pwr7", "pwr7")
+      .Case("pwr8", "pwr8")
       .Case("powerpc", "ppc")
       .Case("powerpc64", "ppc64")
       .Case("powerpc64le", "ppc64le")
@@ -1417,9 +1437,13 @@
     Features.push_back("-fsgsbase");
   }
 
+  // Add features to comply with gcc on Android
   if (Triple.getEnvironment() == llvm::Triple::Android) {
-    // Add sse3 feature to comply with gcc on Android
-    Features.push_back("+sse3");
+    if (Triple.getArch() == llvm::Triple::x86_64) {
+      Features.push_back("+sse4.2");
+      Features.push_back("+popcnt");
+    } else
+      Features.push_back("+ssse3");
   }
 
   // Now add any that the user explicitly requested on the command line,
@@ -1752,8 +1776,8 @@
   if (isa<CompileJobAction>(A))
     return true;
 
-  for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it)
-    if (ContainsCompileAction(*it))
+  for (const auto &Act : *A)
+    if (ContainsCompileAction(Act))
       return true;
 
   return false;
@@ -1769,9 +1793,8 @@
 
   if (RelaxDefault) {
     RelaxDefault = false;
-    for (ActionList::const_iterator it = C.getActions().begin(),
-           ie = C.getActions().end(); it != ie; ++it) {
-      if (ContainsCompileAction(*it)) {
+    for (const auto &Act : C.getActions()) {
+      if (ContainsCompileAction(Act)) {
         RelaxDefault = true;
         break;
       }
@@ -2025,17 +2048,21 @@
 static void addUbsanRT(const ToolChain &TC, const ArgList &Args,
                        ArgStringList &CmdArgs, bool IsCXX,
                        bool HasOtherSanitizerRt) {
+  // Do not link runtime into shared libraries.
+  if (Args.hasArg(options::OPT_shared))
+    return;
+
   // Need a copy of sanitizer_common. This could come from another sanitizer
   // runtime; if we're not including one, include our own copy.
   if (!HasOtherSanitizerRt)
     addSanitizerRTLinkFlags(TC, Args, CmdArgs, "san", true, false);
 
-  addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan", false);
+  addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan", false, true);
 
   // Only include the bits of the runtime which need a C++ ABI library if
   // we're linking in C++ mode.
   if (IsCXX)
-    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan_cxx", false);
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan_cxx", false, true);
 }
 
 static void addDfsanRT(const ToolChain &TC, const ArgList &Args,
@@ -2313,8 +2340,11 @@
     }
   }
 
-  // The make clang go fast button.
-  CmdArgs.push_back("-disable-free");
+  // We normally speed up the clang process a bit by skipping destructors at
+  // exit, but when we're generating diagnostics we can rely on some of the
+  // cleanup.
+  if (!C.isForDiagnostics())
+    CmdArgs.push_back("-disable-free");
 
   // Disable the verification pass in -asserts builds.
 #ifdef NDEBUG
@@ -2415,6 +2445,27 @@
     }
   }
 
+  // OpenBSD-specific defaults for PIE
+  if (getToolChain().getTriple().getOS() == llvm::Triple::OpenBSD) {
+    switch (getToolChain().getTriple().getArch()) {
+    case llvm::Triple::mips64:
+    case llvm::Triple::mips64el:
+    case llvm::Triple::sparc:
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      IsPICLevelTwo = false; // "-fpie"
+      break;
+
+    case llvm::Triple::ppc:
+    case llvm::Triple::sparcv9:
+      IsPICLevelTwo = true; // "-fPIE"
+      break;
+
+    default:
+      break;
+    }
+  }
+
   // For the PIC and PIE flag options, this logic is different from the
   // legacy logic in very old versions of GCC, as that logic was just
   // a bug no one had ever fixed. This logic is both more rational and
@@ -2503,6 +2554,13 @@
 
   // LLVM Code Generator Options.
 
+  if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) {
+    StringRef v = A->getValue();
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back(Args.MakeArgString("-warn-stack-size=" + v));
+    A->claim();
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
     CmdArgs.push_back("-mregparm");
     CmdArgs.push_back(A->getValue());
@@ -2864,8 +2922,10 @@
       // FIXME: we should support specifying dwarf version with
       // -gline-tables-only.
       CmdArgs.push_back("-gline-tables-only");
-      // Default is dwarf-2 for darwin.
-      if (getToolChain().getTriple().isOSDarwin())
+      // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD.
+      const llvm::Triple &Triple = getToolChain().getTriple();
+      if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
+          Triple.getOS() == llvm::Triple::FreeBSD)
         CmdArgs.push_back("-gdwarf-2");
     } else if (A->getOption().matches(options::OPT_gdwarf_2))
       CmdArgs.push_back("-gdwarf-2");
@@ -2875,8 +2935,10 @@
       CmdArgs.push_back("-gdwarf-4");
     else if (!A->getOption().matches(options::OPT_g0) &&
              !A->getOption().matches(options::OPT_ggdb0)) {
-      // Default is dwarf-2 for darwin.
-      if (getToolChain().getTriple().isOSDarwin())
+      // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD.
+      const llvm::Triple &Triple = getToolChain().getTriple();
+      if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
+          Triple.getOS() == llvm::Triple::FreeBSD)
         CmdArgs.push_back("-gdwarf-2");
       else
         CmdArgs.push_back("-g");
@@ -3314,10 +3376,6 @@
   if (Args.getLastArg(options::OPT_fapple_kext))
     CmdArgs.push_back("-fapple-kext");
 
-  if (Args.hasFlag(options::OPT_frewrite_includes,
-                   options::OPT_fno_rewrite_includes, false))
-    CmdArgs.push_back("-frewrite-includes");
-
   Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
@@ -3448,6 +3506,17 @@
     CmdArgs.push_back("-arm-restrict-it");
   }
 
+  if (TT.getArch() == llvm::Triple::arm ||
+      TT.getArch() == llvm::Triple::thumb) {
+    if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
+                                 options::OPT_mno_long_calls)) {
+      if (A->getOption().matches(options::OPT_mlong_calls)) {
+        CmdArgs.push_back("-backend-option");
+        CmdArgs.push_back("-arm-long-calls");
+      }
+    }
+  }
+
   // Forward -f options with positive and negative forms; we translate
   // these by hand.
   if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
@@ -3461,6 +3530,12 @@
   if (Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
     A->render(Args, CmdArgs);
 
+  if (Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
+    A->render(Args, CmdArgs);
+
+  if (Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
+    A->render(Args, CmdArgs);
+
   if (Args.hasArg(options::OPT_mkernel)) {
     if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType))
       CmdArgs.push_back("-fapple-kext");
@@ -3528,44 +3603,51 @@
 
   // -fmodule-name specifies the module that is currently being built (or
   // used for header checking by -fmodule-maps).
-  if (Arg *A = Args.getLastArg(options::OPT_fmodule_name)) {
-    A->claim();
+  if (Arg *A = Args.getLastArg(options::OPT_fmodule_name))
     A->render(Args, CmdArgs);
-  }
 
   // -fmodule-map-file can be used to specify a file containing module
   // definitions.
-  if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file)) {
-    A->claim();
+  if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file))
     A->render(Args, CmdArgs);
-  }
 
-  // If a module path was provided, pass it along. Otherwise, use a temporary
-  // directory.
-  if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) {
-    A->claim();
-    if (HaveModules) {
-      A->render(Args, CmdArgs);
+  // -fmodule-cache-path specifies where our module files should be written.
+  SmallString<128> ModuleCachePath;
+  if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
+    ModuleCachePath = A->getValue();
+  if (HaveModules) {
+    if (C.isForDiagnostics()) {
+      // When generating crash reports, we want to emit the modules along with
+      // the reproduction sources, so we ignore any provided module path.
+      ModuleCachePath = Output.getFilename();
+      llvm::sys::path::replace_extension(ModuleCachePath, ".cache");
+      llvm::sys::path::append(ModuleCachePath, "modules");
+    } else if (ModuleCachePath.empty()) {
+      // No module path was provided: use the default.
+      llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
+                                             ModuleCachePath);
+      llvm::sys::path::append(ModuleCachePath, "org.llvm.clang");
+      llvm::sys::path::append(ModuleCachePath, "ModuleCache");
     }
-  } else if (HaveModules) {
-    SmallString<128> DefaultModuleCache;
-    llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
-                                           DefaultModuleCache);
-    llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
-    llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
     const char Arg[] = "-fmodules-cache-path=";
-    DefaultModuleCache.insert(DefaultModuleCache.begin(),
-                              Arg, Arg + strlen(Arg));
-    CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
+    ModuleCachePath.insert(ModuleCachePath.begin(), Arg, Arg + strlen(Arg));
+    CmdArgs.push_back(Args.MakeArgString(ModuleCachePath));
   }
 
-  if (Arg *A = Args.getLastArg(options::OPT_fmodules_user_build_path)) {
-    A->claim();
-    if (HaveModules) {
-      A->render(Args, CmdArgs);
-    }
+  // When building modules and generating crashdumps, we need to dump a module
+  // dependency VFS alongside the output.
+  if (HaveModules && C.isForDiagnostics()) {
+    SmallString<128> VFSDir(Output.getFilename());
+    llvm::sys::path::replace_extension(VFSDir, ".cache");
+    llvm::sys::path::append(VFSDir, "vfs");
+    CmdArgs.push_back("-module-dependency-dir");
+    CmdArgs.push_back(Args.MakeArgString(VFSDir));
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_fmodules_user_build_path))
+    if (HaveModules)
+      A->render(Args, CmdArgs);
+
   // Pass through all -fmodules-ignore-macro arguments.
   Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
   Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
@@ -3771,9 +3853,10 @@
     }
   }
 
-  // Add exception args.
-  addExceptionArgs(Args, InputType, getToolChain().getTriple(),
-                   KernelOrKext, objcRuntime, CmdArgs);
+  // Handle GCC-style exception args.
+  if (!C.getDriver().IsCLMode())
+    addExceptionArgs(Args, InputType, getToolChain().getTriple(), KernelOrKext,
+                     objcRuntime, CmdArgs);
 
   if (getToolChain().UseSjLjExceptions())
     CmdArgs.push_back("-fsjlj-exceptions");
@@ -3837,6 +3920,14 @@
     D.Diag(diag::err_drv_clang_unsupported)
       << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
 
+  // -finput_charset=UTF-8 is default. Reject others
+  if (Arg *inputCharset = Args.getLastArg(
+          options::OPT_finput_charset_EQ)) {
+      StringRef value = inputCharset->getValue();
+      if (value != "UTF-8")
+          D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args) << value;
+  }
+
   // -fcaret-diagnostics is default.
   if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
                     options::OPT_fno_caret_diagnostics, true))
@@ -3879,9 +3970,8 @@
   // Support both clang's -f[no-]color-diagnostics and gcc's
   // -f[no-]diagnostics-colors[=never|always|auto].
   enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto;
-  for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
-       it != ie; ++it) {
-    const Option &O = (*it)->getOption();
+  for (const auto &Arg : Args) {
+    const Option &O = Arg->getOption();
     if (!O.matches(options::OPT_fcolor_diagnostics) &&
         !O.matches(options::OPT_fdiagnostics_color) &&
         !O.matches(options::OPT_fno_color_diagnostics) &&
@@ -3889,7 +3979,7 @@
         !O.matches(options::OPT_fdiagnostics_color_EQ))
       continue;
 
-    (*it)->claim();
+    Arg->claim();
     if (O.matches(options::OPT_fcolor_diagnostics) ||
         O.matches(options::OPT_fdiagnostics_color)) {
       ShowColors = Colors_On;
@@ -3898,7 +3988,7 @@
       ShowColors = Colors_Off;
     } else {
       assert(O.matches(options::OPT_fdiagnostics_color_EQ));
-      StringRef value((*it)->getValue());
+      StringRef value(Arg->getValue());
       if (value == "always")
         ShowColors = Colors_On;
       else if (value == "never")
@@ -4005,6 +4095,15 @@
   }
 #endif
 
+  // Enable rewrite includes if the user's asked for it or if we're generating
+  // diagnostics.
+  // TODO: Once -module-dependency-dir works with -frewrite-includes it'd be
+  // nice to enable this when doing a crashdump for modules as well.
+  if (Args.hasFlag(options::OPT_frewrite_includes,
+                   options::OPT_fno_rewrite_includes, false) ||
+      (C.isForDiagnostics() && !HaveModules))
+    CmdArgs.push_back("-frewrite-includes");
+
   // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
   if (Arg *A = Args.getLastArg(options::OPT_traditional,
                                options::OPT_traditional_cpp)) {
@@ -4055,10 +4154,7 @@
     assert(Output.isNothing() && "Invalid output.");
   }
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
-
+  for (const auto &II : Inputs) {
     addDashXForInput(Args, II, CmdArgs);
 
     if (II.isFilename())
@@ -4075,9 +4171,8 @@
   // analysis.
   if (getToolChain().UseDwarfDebugFlags()) {
     ArgStringList OriginalArgs;
-    for (ArgList::const_iterator it = Args.begin(),
-           ie = Args.end(); it != ie; ++it)
-      (*it)->render(Args, OriginalArgs);
+    for (const auto &Arg : Args)
+      Arg->render(Args, OriginalArgs);
 
     SmallString<256> Flags;
     Flags += Exec;
@@ -4105,18 +4200,9 @@
   if (Args.hasArg(options::OPT__SLASH_fallback) &&
       Output.getType() == types::TY_Object &&
       (InputType == types::TY_C || InputType == types::TY_CXX)) {
-    tools::visualstudio::Compile CL(getToolChain());
-    Command *CLCommand = CL.GetCommand(C, JA, Output, Inputs, Args,
-                                       LinkingOutput);
-    // RTTI support in clang-cl is a work in progress.  Fall back to MSVC early
-    // if we are using 'clang-cl /fallback /GR'.
-    // FIXME: Remove this when RTTI is finished.
-    if (Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti, false)) {
-      D.Diag(diag::warn_drv_rtti_fallback) << CLCommand->getExecutable();
-      C.addCommand(CLCommand);
-    } else {
-      C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand));
-    }
+    Command *CLCommand = getCLFallback()->GetCommand(C, JA, Output, Inputs,
+                                                     Args, LinkingOutput);
+    C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand));
   } else {
     C.addCommand(new Command(JA, *this, Exec, CmdArgs));
   }
@@ -4274,6 +4360,45 @@
   return runtime;
 }
 
+static bool maybeConsumeDash(const std::string &EH, size_t &I) {
+  bool HaveDash = (I + 1 < EH.size() && EH[I + 1] == '-');
+  I += HaveDash;
+  return !HaveDash;
+}
+
+struct EHFlags {
+  EHFlags() : Synch(false), Asynch(false), NoExceptC(false) {}
+  bool Synch;
+  bool Asynch;
+  bool NoExceptC;
+};
+
+/// /EH controls whether to run destructor cleanups when exceptions are
+/// thrown.  There are three modifiers:
+/// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
+/// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
+///      The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
+/// - c: Assume that extern "C" functions are implicitly noexcept.  This
+///      modifier is an optimization, so we ignore it for now.
+/// The default is /EHs-c-, meaning cleanups are disabled.
+static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
+  EHFlags EH;
+  std::vector<std::string> EHArgs = Args.getAllArgValues(options::OPT__SLASH_EH);
+  for (auto EHVal : EHArgs) {
+    for (size_t I = 0, E = EHVal.size(); I != E; ++I) {
+      switch (EHVal[I]) {
+      case 'a': EH.Asynch = maybeConsumeDash(EHVal, I); continue;
+      case 'c': EH.NoExceptC = maybeConsumeDash(EHVal, I); continue;
+      case 's': EH.Synch = maybeConsumeDash(EHVal, I); continue;
+      default: break;
+      }
+      D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
+      break;
+    }
+  }
+  return EH;
+}
+
 void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
   unsigned RTOptionID = options::OPT__SLASH_MT;
 
@@ -4322,11 +4447,25 @@
   if (Arg *A = Args.getLastArg(options::OPT_show_includes))
     A->render(Args, CmdArgs);
 
-  // RTTI is currently not supported, so disable it by default.
-  if (!Args.hasArg(options::OPT_frtti, options::OPT_fno_rtti))
-    CmdArgs.push_back("-fno-rtti");
+  // This controls whether or not we emit RTTI data for polymorphic types.
+  if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
+                   /*default=*/false))
+    CmdArgs.push_back("-fno-rtti-data");
 
   const Driver &D = getToolChain().getDriver();
+  EHFlags EH = parseClangCLEHFlags(D, Args);
+  // FIXME: Do something with NoExceptC.
+  if (EH.Synch || EH.Asynch) {
+    CmdArgs.push_back("-fexceptions");
+    CmdArgs.push_back("-fcxx-exceptions");
+  }
+
+  // /EP should expand to -E -P.
+  if (Args.hasArg(options::OPT__SLASH_EP)) {
+    CmdArgs.push_back("-E");
+    CmdArgs.push_back("-P");
+  }
+
   Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
   Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
   if (MostGeneralArg && BestCaseArg)
@@ -4365,6 +4504,12 @@
   }
 }
 
+visualstudio::Compile *Clang::getCLFallback() const {
+  if (!CLFallback)
+    CLFallback.reset(new visualstudio::Compile(getToolChain()));
+  return CLFallback.get();
+}
+
 void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
                            const InputInfo &Output,
                            const InputInfoList &Inputs,
@@ -4452,9 +4597,8 @@
   // analysis.
   if (getToolChain().UseDwarfDebugFlags()) {
     ArgStringList OriginalArgs;
-    for (ArgList::const_iterator it = Args.begin(),
-           ie = Args.end(); it != ie; ++it)
-      (*it)->render(Args, OriginalArgs);
+    for (const auto &Arg : Args)
+      Arg->render(Args, OriginalArgs);
 
     SmallString<256> Flags;
     const char *Exec = getToolChain().getDriver().getClangProgramPath();
@@ -4511,9 +4655,7 @@
   const Driver &D = getToolChain().getDriver();
   ArgStringList CmdArgs;
 
-  for (ArgList::const_iterator
-         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
-    Arg *A = *it;
+  for (const auto &A : Args) {
     if (forwardToGCC(A->getOption())) {
       // Don't forward any -g arguments to assembly steps.
       if (isa<AssembleJobAction>(JA) &&
@@ -4582,10 +4724,7 @@
   //
   // FIXME: For the linker case specifically, can we safely convert
   // inputs into '-Wl,' options?
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
-
+  for (const auto &II : Inputs) {
     // Don't try to pass LLVM or AST inputs to a generic gcc.
     if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
         II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
@@ -4704,10 +4843,7 @@
   //
   // FIXME: For the linker case specifically, can we safely convert
   // inputs into '-Wl,' options?
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
-
+  for (const auto &II : Inputs) {
     // Don't try to pass LLVM or AST inputs to a generic gcc.
     if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
         II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
@@ -4728,11 +4864,10 @@
   }
 
   const char *GCCName = "hexagon-as";
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
-
 }
+
 void hexagon::Link::RenderExtraToolArgs(const JobAction &JA,
                                     ArgStringList &CmdArgs) const {
   // The types are (hopefully) good enough.
@@ -4774,10 +4909,8 @@
   //----------------------------------------------------------------------------
   //
   //----------------------------------------------------------------------------
-  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
-         e = ToolChain.ExtraOpts.end();
-       i != e; ++i)
-    CmdArgs.push_back(i->c_str());
+  for (const auto &Opt : ToolChain.ExtraOpts)
+    CmdArgs.push_back(Opt.c_str());
 
   std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
   CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
@@ -4853,12 +4986,8 @@
   // Library Search Paths
   //----------------------------------------------------------------------------
   const ToolChain::path_list &LibPaths = ToolChain.getFilePaths();
-  for (ToolChain::path_list::const_iterator
-         i = LibPaths.begin(),
-         e = LibPaths.end();
-       i != e;
-       ++i)
-    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+  for (const auto &LibPath : LibPaths)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
 
   //----------------------------------------------------------------------------
   //
@@ -4906,9 +5035,6 @@
 }
 // Hexagon tools end.
 
-/// getARMCPUForMArch - Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting
-//
-// FIXME: tblgen this.
 const char *arm::getARMCPUForMArch(const ArgList &Args,
                                    const llvm::Triple &Triple) {
   StringRef MArch;
@@ -4930,6 +5056,14 @@
     }
   }
 
+  return driver::getARMCPUForMArch(MArch, Triple);
+}
+
+/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
+//
+// FIXME: tblgen this.
+const char *driver::getARMCPUForMArch(StringRef MArch,
+                                      const llvm::Triple &Triple) {
   switch (Triple.getOS()) {
   case llvm::Triple::NetBSD:
     if (MArch == "armv6")
@@ -5060,6 +5194,21 @@
   return A && (A->getValue() == StringRef(Value));
 }
 
+bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
+  if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
+    return llvm::StringSwitch<bool>(NaNArg->getValue())
+               .Case("2008", true)
+               .Case("legacy", false)
+               .Default(false);
+
+  // NaN2008 is the default for MIPS32r6/MIPS64r6.
+  return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
+             .Cases("mips32r6", "mips64r6", true)
+             .Default(false);
+
+  return false;
+}
+
 llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
   // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
   // archs which Darwin doesn't use.
@@ -5225,9 +5374,8 @@
   // We only need to generate a temp path for LTO if we aren't compiling object
   // files. When compiling source files, we run 'dsymutil' after linking. We
   // don't run 'dsymutil' when compiling object files.
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it)
-    if (it->getType() != types::TY_Object)
+  for (const auto &Input : Inputs)
+    if (Input.getType() != types::TY_Object)
       return true;
 
   return false;
@@ -5428,8 +5576,8 @@
   /// 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)) {
-    for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I)
-      (*I)->claim();
+    for (const auto &Arg : Args)
+      Arg->claim();
     const char *Exec =
       Args.MakeArgString(getToolChain().GetProgramPath("touch"));
     CmdArgs.push_back(Output.getFilename());
@@ -5530,7 +5678,7 @@
   Args.AddAllArgs(CmdArgs, options::OPT_F);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5547,14 +5695,12 @@
   CmdArgs.push_back("-output");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs) {
     assert(II.isFilename() && "Unexpected lipo input.");
     CmdArgs.push_back(II.getFilename());
   }
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5614,18 +5760,13 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
-
 void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
                                   const InputInfo &Output,
                                   const InputInfoList &Inputs,
@@ -5727,7 +5868,7 @@
   addProfileRT(getToolChain(), Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5744,14 +5885,10 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("gas"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("gas"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5839,7 +5976,7 @@
   addProfileRT(getToolChain(), Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5905,11 +6042,8 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
   const char *Exec =
     Args.MakeArgString(getToolChain().GetProgramPath("as"));
@@ -6044,7 +6178,7 @@
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6061,14 +6195,10 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6184,7 +6314,7 @@
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6262,14 +6392,10 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6370,9 +6496,8 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   const ToolChain::path_list Paths = ToolChain.getFilePaths();
-  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
-       i != e; ++i)
-    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+  for (const auto &Path : Paths)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
   Args.AddAllArgs(CmdArgs, options::OPT_e);
   Args.AddAllArgs(CmdArgs, options::OPT_s);
@@ -6453,7 +6578,7 @@
   addProfileRT(ToolChain, Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(ToolChain.GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6524,11 +6649,8 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
   const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
@@ -6709,7 +6831,7 @@
 
   addProfileRT(getToolChain(), Args, CmdArgs);
 
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6726,7 +6848,10 @@
   if (getToolChain().getArch() == llvm::Triple::x86) {
     CmdArgs.push_back("--32");
   } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
-    CmdArgs.push_back("--64");
+    if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32)
+      CmdArgs.push_back("--x32");
+    else
+      CmdArgs.push_back("--64");
   } else if (getToolChain().getArch() == llvm::Triple::ppc) {
     CmdArgs.push_back("-a32");
     CmdArgs.push_back("-mppc");
@@ -6829,14 +6954,10 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 
   // Handle the debug info splitting at object creation time if we're
@@ -6910,22 +7031,29 @@
     else
       return "/lib/ld-linux.so.3";              /* TODO: check which dynamic linker name.  */
   } else if (ToolChain.getArch() == llvm::Triple::mips ||
-             ToolChain.getArch() == llvm::Triple::mipsel)
+             ToolChain.getArch() == llvm::Triple::mipsel) {
+    if (mips::isNaN2008(Args, ToolChain.getTriple()))
+      return "/lib/ld-linux-mipsn8.so.1";
     return "/lib/ld.so.1";
-  else if (ToolChain.getArch() == llvm::Triple::mips64 ||
-           ToolChain.getArch() == llvm::Triple::mips64el) {
+  } else if (ToolChain.getArch() == llvm::Triple::mips64 ||
+             ToolChain.getArch() == llvm::Triple::mips64el) {
     if (mips::hasMipsAbiArg(Args, "n32"))
-      return "/lib32/ld.so.1";
-    else
-      return "/lib64/ld.so.1";
+      return mips::isNaN2008(Args, ToolChain.getTriple())
+                 ? "/lib32/ld-linux-mipsn8.so.1" : "/lib32/ld.so.1";
+    return mips::isNaN2008(Args, ToolChain.getTriple())
+               ? "/lib64/ld-linux-mipsn8.so.1" : "/lib64/ld.so.1";
   } else if (ToolChain.getArch() == llvm::Triple::ppc)
     return "/lib/ld.so.1";
   else if (ToolChain.getArch() == llvm::Triple::ppc64 ||
-           ToolChain.getArch() == llvm::Triple::ppc64le ||
            ToolChain.getArch() == llvm::Triple::systemz)
     return "/lib64/ld64.so.1";
+  else if (ToolChain.getArch() == llvm::Triple::ppc64le)
+    return "/lib64/ld64.so.2";
   else if (ToolChain.getArch() == llvm::Triple::sparcv9)
     return "/lib64/ld-linux.so.2";
+  else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
+           ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
+    return "/libx32/ld-linux-x32.so.2";
   else
     return "/lib64/ld-linux-x86-64.so.2";
 }
@@ -6986,10 +7114,8 @@
   if (Args.hasArg(options::OPT_s))
     CmdArgs.push_back("-s");
 
-  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
-         e = ToolChain.ExtraOpts.end();
-       i != e; ++i)
-    CmdArgs.push_back(i->c_str());
+  for (const auto &Opt : ToolChain.ExtraOpts)
+    CmdArgs.push_back(Opt.c_str());
 
   if (!Args.hasArg(options::OPT_static)) {
     CmdArgs.push_back("--eh-frame-hdr");
@@ -7038,6 +7164,9 @@
   }
   else if (ToolChain.getArch() == llvm::Triple::systemz)
     CmdArgs.push_back("elf64_s390");
+  else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
+           ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
+    CmdArgs.push_back("elf32_x86_64");
   else
     CmdArgs.push_back("elf_x86_64");
 
@@ -7051,9 +7180,6 @@
       CmdArgs.push_back("-static");
   } else if (Args.hasArg(options::OPT_shared)) {
     CmdArgs.push_back("-shared");
-    if (isAndroid) {
-      CmdArgs.push_back("-Bsymbolic");
-    }
   }
 
   if (ToolChain.getArch() == llvm::Triple::arm ||
@@ -7104,12 +7230,12 @@
   }
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_u);
 
   const ToolChain::path_list Paths = ToolChain.getFilePaths();
 
-  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
-       i != e; ++i)
-    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+  for (const auto &Path : Paths)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
 
   if (D.IsUsingLTO(Args))
     AddGoldPlugin(ToolChain, Args, CmdArgs);
@@ -7169,8 +7295,9 @@
       }
       AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
 
-      if (Args.hasArg(options::OPT_pthread) ||
-          Args.hasArg(options::OPT_pthreads) || UsedOpenMPLib != LibUnknown)
+      if ((Args.hasArg(options::OPT_pthread) ||
+           Args.hasArg(options::OPT_pthreads) || UsedOpenMPLib != LibUnknown) &&
+          !isAndroid)
         CmdArgs.push_back("-lpthread");
 
       CmdArgs.push_back("-lc");
@@ -7206,20 +7333,15 @@
                                    const char *LinkingOutput) const {
   ArgStringList CmdArgs;
 
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
-                       options::OPT_Xassembler);
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -7273,7 +7395,7 @@
          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
   }
 
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -7293,20 +7415,15 @@
   if (getToolChain().getArch() == llvm::Triple::x86)
     CmdArgs.push_back("--32");
 
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
-                       options::OPT_Xassembler);
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -7456,8 +7573,7 @@
 
   addProfileRT(getToolChain(), Args, CmdArgs);
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -7524,13 +7640,11 @@
   Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
 
   // Add filenames immediately.
-  for (InputInfoList::const_iterator
-       it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    if (it->isFilename())
-      CmdArgs.push_back(it->getFilename());
+  for (const auto &Input : Inputs)
+    if (Input.isFilename())
+      CmdArgs.push_back(Input.getFilename());
     else
-      it->getInputArg().renderAsInput(Args, CmdArgs);
-  }
+      Input.getInputArg().renderAsInput(Args, CmdArgs);
 
   const char *Exec =
     Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
@@ -7555,14 +7669,9 @@
   if (!OptPath.hasValue())
     return FallbackName;
 
-#ifdef LLVM_ON_WIN32
-  const StringRef PathSeparators = ";";
-#else
-  const StringRef PathSeparators = ":";
-#endif
-
+  const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
   SmallVector<StringRef, 8> PathSegments;
-  llvm::SplitString(OptPath.getValue(), PathSegments, PathSeparators);
+  llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
 
   for (size_t i = 0, e = PathSegments.size(); i != e; ++i) {
     const StringRef &PathSegment = PathSegments[i];
@@ -7612,9 +7721,9 @@
   // Flags for which clang-cl have an alias.
   // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
 
-  if (Arg *A = Args.getLastArg(options::OPT_frtti, options::OPT_fno_rtti))
-    CmdArgs.push_back(A->getOption().getID() == options::OPT_frtti ? "/GR"
-                                                                   : "/GR-");
+  if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
+                   /*default=*/false))
+    CmdArgs.push_back("/GR-");
   if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
                                options::OPT_fno_function_sections))
     CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
@@ -7630,12 +7739,13 @@
     CmdArgs.push_back("/Z7");
 
   std::vector<std::string> Includes = Args.getAllArgValues(options::OPT_include);
-  for (size_t I = 0, E = Includes.size(); I != E; ++I)
-    CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Includes[I]));
+  for (const auto &Include : Includes)
+    CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
 
   // Flags that can simply be passed through.
   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
+  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
 
   // The order of these flags is relevant, so pick the last one.
   if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
@@ -7661,7 +7771,6 @@
 
   const Driver &D = getToolChain().getDriver();
   std::string Exec = FindFallback("cl.exe", D.getClangProgramPath());
-
   return new Command(JA, *this, Args.MakeArgString(Exec), CmdArgs);
 }
 
@@ -7695,14 +7804,10 @@
   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
                        options::OPT_Xassembler);
 
-  for (InputInfoList::const_iterator
-       it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -7729,7 +7834,6 @@
 
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index 575c988..bc7f58b 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -29,6 +29,11 @@
 }
 
 namespace tools {
+
+namespace visualstudio {
+  class Compile;
+}
+
 using llvm::opt::ArgStringList;
 
   /// \brief Clang compiler tool.
@@ -78,6 +83,10 @@
     void AddClangCLArgs(const llvm::opt::ArgList &Args,
                         llvm::opt::ArgStringList &CmdArgs) const;
 
+    visualstudio::Compile *getCLFallback() const;
+
+    mutable std::unique_ptr<visualstudio::Compile> CLFallback;
+
   public:
     Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {}
 
@@ -209,6 +218,7 @@
 
 namespace mips {
   bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
+  bool isNaN2008(const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
 }
 
 namespace darwin {
@@ -562,7 +572,7 @@
   };
 } // end namespace dragonfly
 
-  /// Visual studio tools.
+/// Visual studio tools.
 namespace visualstudio {
   class LLVM_LIBRARY_VISIBILITY Link : public Tool {
   public:
diff --git a/lib/Driver/WindowsToolChain.cpp b/lib/Driver/WindowsToolChain.cpp
index 5d4bbb5..913425a 100644
--- a/lib/Driver/WindowsToolChain.cpp
+++ b/lib/Driver/WindowsToolChain.cpp
@@ -14,6 +14,7 @@
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -21,11 +22,15 @@
 
 // Include the necessary headers to interface with the Windows registry and
 // environment.
-#ifdef _MSC_VER
+#if defined(LLVM_ON_WIN32)
+#define USE_WIN32
+#endif
+
+#ifdef USE_WIN32
   #define WIN32_LEAN_AND_MEAN
   #define NOGDI
   #define NOMINMAX
-  #include <Windows.h>
+  #include <windows.h>
 #endif
 
 using namespace clang::driver;
@@ -54,7 +59,11 @@
 }
 
 bool Windows::IsUnwindTablesDefault() const {
-  return getArch() == llvm::Triple::x86_64;
+  // FIXME: LLVM's lowering of Win64 data is broken right now.  MSVC's linker
+  // says that our object files provide invalid .pdata contributions.  Until
+  // that is fixed, don't ask for unwind tables.
+  return false;
+  //return getArch() == llvm::Triple::x86_64;
 }
 
 bool Windows::isPICDefault() const {
@@ -69,9 +78,6 @@
   return getArch() == llvm::Triple::x86_64;
 }
 
-// FIXME: This probably should goto to some platform utils place.
-#ifdef _MSC_VER
-
 /// \brief Read registry string.
 /// This also supports a means to look for high-versioned keys by use
 /// of a $VERSION placeholder in the key path.
@@ -82,6 +88,9 @@
 /// characters are compared.
 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
                                     char *value, size_t maxLength) {
+#ifndef USE_WIN32
+  return false;
+#else
   HKEY hRootKey = NULL;
   HKEY hKey = NULL;
   const char* subKey = NULL;
@@ -183,6 +192,7 @@
     }
   }
   return returnValue;
+#endif // USE_WIN32
 }
 
 /// \brief Get Windows SDK installation directory.
@@ -202,7 +212,7 @@
   return false;
 }
 
-  // Get Visual Studio installation directory.
+// Get Visual Studio installation directory.
 static bool getVisualStudioDir(std::string &path) {
   // First check the environment variables that vsvars32.bat sets.
   const char* vcinstalldir = getenv("VCINSTALLDIR");
@@ -244,25 +254,11 @@
   const char *vs100comntools = getenv("VS100COMNTOOLS");
   const char *vs90comntools = getenv("VS90COMNTOOLS");
   const char *vs80comntools = getenv("VS80COMNTOOLS");
-  const char *vscomntools = NULL;
 
-  // Try to find the version that we were compiled with
-  if(false) {}
-  #if (_MSC_VER >= 1600)  // VC100
-  else if(vs100comntools) {
-    vscomntools = vs100comntools;
-  }
-  #elif (_MSC_VER == 1500) // VC80
-  else if(vs90comntools) {
-    vscomntools = vs90comntools;
-  }
-  #elif (_MSC_VER == 1400) // VC80
-  else if(vs80comntools) {
-    vscomntools = vs80comntools;
-  }
-  #endif
-  // Otherwise find any version we can
-  else if (vs100comntools)
+  const char *vscomntools = nullptr;
+
+  // Find any version we can
+  if (vs100comntools)
     vscomntools = vs100comntools;
   else if (vs90comntools)
     vscomntools = vs90comntools;
@@ -277,8 +273,6 @@
   return false;
 }
 
-#endif // _MSC_VER
-
 void Windows::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                         ArgStringList &CC1Args) const {
   if (DriverArgs.hasArg(options::OPT_nostdinc))
@@ -293,7 +287,6 @@
   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
     return;
 
-#ifdef _MSC_VER
   // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
   if (const char *cl_include_dir = getenv("INCLUDE")) {
     SmallVector<StringRef, 8> Dirs;
@@ -328,6 +321,7 @@
   }
 
   // As a fallback, select default install paths.
+  // FIXME: Don't guess drives and paths like this on Windows.
   const StringRef Paths[] = {
     "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
     "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
@@ -336,7 +330,6 @@
     "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
   };
   addSystemIncludes(DriverArgs, CC1Args, Paths);
-#endif // _MSC_VER
 }
 
 void Windows::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 7485e0d..2af16fc 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -112,6 +112,15 @@
     return false;
   if (Current.isMemberAccess() && State.Stack.back().ContainsUnwrappedBuilder)
     return false;
+
+  // Don't create a 'hanging' indent if there are multiple blocks in a single
+  // statement.
+  if (Style.Language == FormatStyle::LK_JavaScript &&
+      Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
+      State.Stack[State.Stack.size() - 2].JSFunctionInlined &&
+      State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks)
+    return false;
+
   return !State.Stack.back().NoLineBreak;
 }
 
@@ -137,7 +146,8 @@
   if (Style.AlwaysBreakBeforeMultilineStrings &&
       State.Column > State.Stack.back().Indent && // Breaking saves columns.
       !Previous.isOneOf(tok::kw_return, tok::lessless, tok::at) &&
-      Previous.Type != TT_InlineASMColon && nextIsMultilineString(State))
+      Previous.Type != TT_InlineASMColon &&
+      Previous.Type != TT_ConditionalExpr && nextIsMultilineString(State))
     return true;
   if (((Previous.Type == TT_DictLiteral && Previous.is(tok::l_brace)) ||
        Previous.Type == TT_ArrayInitializerLSquare) &&
@@ -185,7 +195,7 @@
       State.Stack.back().FirstLessLess == 0)
     return true;
 
-  if (Current.Type == TT_ObjCSelectorName &&
+  if (Current.Type == TT_SelectorName &&
       State.Stack.back().ObjCSelectorNameFound &&
       State.Stack.back().BreakBeforeParameter)
     return true;
@@ -193,10 +203,12 @@
       !Current.isTrailingComment())
     return true;
 
-  if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) &&
-      State.Line->MightBeFunctionDecl &&
-      State.Stack.back().BreakBeforeParameter && Current.NestingLevel == 0)
+  // If the return type spans multiple lines, wrap before the function name.
+  if ((Current.Type == TT_FunctionDeclarationName ||
+       Current.is(tok::kw_operator)) &&
+      State.Stack.back().BreakBeforeParameter)
     return true;
+
   if (startsSegmentOfBuilderTypeCall(Current) &&
       (State.Stack.back().CallContinuation != 0 ||
        (State.Stack.back().BreakBeforeParameter &&
@@ -268,7 +280,7 @@
     Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, /*IndentLevel=*/0,
                                   Spaces, State.Column + Spaces);
 
-  if (Current.Type == TT_ObjCSelectorName &&
+  if (Current.Type == TT_SelectorName &&
       !State.Stack.back().ObjCSelectorNameFound) {
     if (Current.LongestObjCSelectorName == 0)
       State.Stack.back().AlignColons = false;
@@ -294,7 +306,7 @@
     // Treat the condition inside an if as if it was a second function
     // parameter, i.e. let nested calls have a continuation indent.
     State.Stack.back().LastSpace = State.Column;
-  else if (Current.isNot(tok::comment) &&
+  else if (!Current.isOneOf(tok::comment, tok::caret) &&
            (Previous.is(tok::comma) ||
             (Previous.is(tok::colon) && Previous.Type == TT_ObjCMethodExpr)))
     State.Stack.back().LastSpace = State.Column;
@@ -363,7 +375,7 @@
   if (NextNonComment->isMemberAccess()) {
     if (State.Stack.back().CallContinuation == 0)
       State.Stack.back().CallContinuation = State.Column;
-  } else if (NextNonComment->Type == TT_ObjCSelectorName) {
+  } else if (NextNonComment->Type == TT_SelectorName) {
     if (!State.Stack.back().ObjCSelectorNameFound) {
       if (NextNonComment->LongestObjCSelectorName == 0) {
         State.Stack.back().AlignColons = false;
@@ -404,10 +416,8 @@
     State.Stack.back().BreakBeforeParameter = true;
 
   if (!DryRun) {
-    unsigned Newlines = 1;
-    if (Current.is(tok::comment))
-      Newlines = std::max(Newlines, std::min(Current.NewlinesBefore,
-                                             Style.MaxEmptyLinesToKeep + 1));
+    unsigned Newlines = std::max(
+        1u, std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1));
     Whitespaces.replaceWhitespace(Current, Newlines,
                                   State.Stack.back().IndentLevel, State.Column,
                                   State.Column, State.Line->InPPDirective);
@@ -439,7 +449,9 @@
 
   // If we break after { or the [ of an array initializer, we should also break
   // before the corresponding } or ].
-  if (Previous.is(tok::l_brace) || Previous.Type == TT_ArrayInitializerLSquare)
+  if (PreviousNonComment &&
+      (PreviousNonComment->is(tok::l_brace) ||
+       PreviousNonComment->Type == TT_ArrayInitializerLSquare))
     State.Stack.back().BreakBeforeClosingBrace = true;
 
   if (State.Stack.back().AvoidBinPacking) {
@@ -508,13 +520,11 @@
     return State.Stack.back().VariablePos;
   if ((PreviousNonComment && (PreviousNonComment->ClosesTemplateDeclaration ||
                               PreviousNonComment->Type == TT_AttributeParen)) ||
-      ((NextNonComment->Type == TT_StartOfName ||
-        NextNonComment->is(tok::kw_operator)) &&
-       Current.NestingLevel == 0 &&
-       (!Style.IndentFunctionDeclarationAfterType ||
-        State.Line->StartsDefinition)))
+      (!Style.IndentWrappedFunctionNames &&
+       (NextNonComment->is(tok::kw_operator) ||
+        NextNonComment->Type == TT_FunctionDeclarationName)))
     return std::max(State.Stack.back().LastSpace, State.Stack.back().Indent);
-  if (NextNonComment->Type == TT_ObjCSelectorName) {
+  if (NextNonComment->Type == TT_SelectorName) {
     if (!State.Stack.back().ObjCSelectorNameFound) {
       if (NextNonComment->LongestObjCSelectorName == 0) {
         return State.Stack.back().Indent;
@@ -587,10 +597,8 @@
   if (Current.isMemberAccess())
     State.Stack.back().StartOfFunctionCall =
         Current.LastOperator ? 0 : State.Column + Current.ColumnWidth;
-  if (Current.Type == TT_ObjCSelectorName)
+  if (Current.Type == TT_SelectorName)
     State.Stack.back().ObjCSelectorNameFound = true;
-  if (Current.Type == TT_LambdaLSquare)
-    ++State.Stack.back().LambdasFound;
   if (Current.Type == TT_CtorInitializerColon) {
     // Indent 2 from the column, so:
     // SomeClass::SomeClass()
@@ -736,27 +744,60 @@
   }
 }
 
-void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
-  const FormatToken &Current = *State.NextToken;
-
-  // Remove scopes created by fake parenthesis.
-  if (Current.isNot(tok::r_brace) ||
-      (Current.MatchingParen && Current.MatchingParen->BlockKind != BK_Block)) {
-    // Don't remove FakeRParens attached to r_braces that surround nested blocks
-    // as they will have been removed early (see above).
-    for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
-      unsigned VariablePos = State.Stack.back().VariablePos;
-      assert(State.Stack.size() > 1);
-      if (State.Stack.size() == 1) {
-        // Do not pop the last element.
-        break;
-      }
-      State.Stack.pop_back();
-      State.Stack.back().VariablePos = VariablePos;
+// Remove the fake r_parens after 'Tok'.
+static void consumeRParens(LineState& State, const FormatToken &Tok) {
+  for (unsigned i = 0, e = Tok.FakeRParens; i != e; ++i) {
+    unsigned VariablePos = State.Stack.back().VariablePos;
+    assert(State.Stack.size() > 1);
+    if (State.Stack.size() == 1) {
+      // Do not pop the last element.
+      break;
     }
+    State.Stack.pop_back();
+    State.Stack.back().VariablePos = VariablePos;
   }
 }
 
+// Returns whether 'Tok' opens or closes a scope requiring special handling
+// of the subsequent fake r_parens.
+//
+// For example, if this is an l_brace starting a nested block, we pretend (wrt.
+// to indentation) that we already consumed the corresponding r_brace. Thus, we
+// remove all ParenStates caused by fake parentheses that end at the r_brace.
+// The net effect of this is that we don't indent relative to the l_brace, if
+// the nested block is the last parameter of a function. This formats:
+//
+//   SomeFunction(a, [] {
+//     f();  // break
+//   });
+//
+// instead of:
+//   SomeFunction(a, [] {
+//                     f();  // break
+//                   });
+static bool fakeRParenSpecialCase(const LineState &State) {
+  const FormatToken &Tok = *State.NextToken;
+  if (!Tok.MatchingParen)
+    return false;
+  const FormatToken *Left = &Tok;
+  if (Tok.isOneOf(tok::r_brace, tok::r_square))
+    Left = Tok.MatchingParen;
+  return !State.Stack.back().HasMultipleNestedBlocks &&
+         Left->isOneOf(tok::l_brace, tok::l_square) &&
+         (Left->BlockKind == BK_Block ||
+          Left->Type == TT_ArrayInitializerLSquare ||
+          Left->Type == TT_DictLiteral);
+}
+
+void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
+  // Don't remove FakeRParens attached to r_braces that surround nested blocks
+  // as they will have been removed early (see above).
+  if (fakeRParenSpecialCase(State))
+    return;
+
+  consumeRParens(State, *State.NextToken);
+}
+
 void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
                                                     bool Newline) {
   const FormatToken &Current = *State.NextToken;
@@ -773,6 +814,9 @@
   bool AvoidBinPacking;
   bool BreakBeforeParameter = false;
   if (Current.is(tok::l_brace) || Current.Type == TT_ArrayInitializerLSquare) {
+    if (fakeRParenSpecialCase(State))
+      consumeRParens(State, *Current.MatchingParen);
+
     NewIndent = State.Stack.back().LastSpace;
     if (Current.opensBlockTypeList(Style)) {
       NewIndent += Style.IndentWidth;
@@ -812,6 +856,7 @@
                                    State.Stack.back().LastSpace,
                                    AvoidBinPacking, NoLineBreak));
   State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
+  State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
 }
 
 void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
@@ -824,9 +869,9 @@
   if (State.Stack.size() > 1 &&
       (Current.isOneOf(tok::r_paren, tok::r_square) ||
        (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
-       State.NextToken->Type == TT_TemplateCloser)) {
+       State.NextToken->Type == TT_TemplateCloser))
     State.Stack.pop_back();
-  }
+
   if (Current.is(tok::r_square)) {
     // If this ends the array subscript expr, reset the corresponding value.
     const FormatToken *NextNonComment = Current.getNextNonComment();
@@ -836,35 +881,10 @@
 }
 
 void ContinuationIndenter::moveStateToNewBlock(LineState &State) {
-  // If this is an l_brace starting a nested block, we pretend (wrt. to
-  // indentation) that we already consumed the corresponding r_brace. Thus, we
-  // remove all ParenStates caused by fake parentheses that end at the r_brace.
-  // The net effect of this is that we don't indent relative to the l_brace, if
-  // the nested block is the last parameter of a function. For example, this
-  // formats:
-  //
-  //   SomeFunction(a, [] {
-  //     f();  // break
-  //   });
-  //
-  // instead of:
-  //   SomeFunction(a, [] {
-  //                     f();  // break
-  //                   });
-  //
   // If we have already found more than one lambda introducers on this level, we
   // opt out of this because similarity between the lambdas is more important.
-  if (State.Stack.back().LambdasFound <= 1) {
-    for (unsigned i = 0; i != State.NextToken->MatchingParen->FakeRParens;
-         ++i) {
-      assert(State.Stack.size() > 1);
-      if (State.Stack.size() == 1) {
-        // Do not pop the last element.
-        break;
-      }
-      State.Stack.pop_back();
-    }
-  }
+  if (fakeRParenSpecialCase(State))
+    consumeRParens(State, *State.NextToken->MatchingParen);
 
   // For some reason, ObjC blocks are indented like continuations.
   unsigned NewIndent = State.Stack.back().LastSpace +
diff --git a/lib/Format/ContinuationIndenter.h b/lib/Format/ContinuationIndenter.h
index 4733bda0..0969a8c 100644
--- a/lib/Format/ContinuationIndenter.h
+++ b/lib/Format/ContinuationIndenter.h
@@ -151,8 +151,8 @@
         StartOfFunctionCall(0), StartOfArraySubscripts(0),
         NestedNameSpecifierContinuation(0), CallContinuation(0), VariablePos(0),
         ContainsLineBreak(false), ContainsUnwrappedBuilder(0),
-        AlignColons(true), ObjCSelectorNameFound(false), LambdasFound(0),
-        JSFunctionInlined(false) {}
+        AlignColons(true), ObjCSelectorNameFound(false),
+        HasMultipleNestedBlocks(false), JSFunctionInlined(false) {}
 
   /// \brief The position to which a specific parenthesis level needs to be
   /// indented.
@@ -247,11 +247,11 @@
   /// the same token.
   bool ObjCSelectorNameFound;
 
-  /// \brief Counts the number of lambda introducers found on this level.
+  /// \brief \c true if there are multiple nested blocks inside these parens.
   ///
   /// Not considered for memoization as it will always have the same value at
   /// the same token.
-  unsigned LambdasFound;
+  bool HasMultipleNestedBlocks;
 
   // \brief The previous JavaScript 'function' keyword is not wrapped to a new
   // line.
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 7d0e102..be9bbed 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -97,6 +97,20 @@
 };
 
 template <>
+struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
+  static void enumeration(IO &IO,
+                          FormatStyle::PointerAlignmentStyle &Value) {
+    IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
+    IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
+    IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
+
+    // For backward compability.
+    IO.enumCase(Value, "true", FormatStyle::PAS_Left);
+    IO.enumCase(Value, "false", FormatStyle::PAS_Right);
+  }
+};
+
+template <>
 struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
   static void enumeration(IO &IO,
                           FormatStyle::SpaceBeforeParensOptions &Value) {
@@ -173,10 +187,14 @@
     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
                    Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
-    IO.mapOptional("DerivePointerBinding", Style.DerivePointerBinding);
+    IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
     IO.mapOptional("ExperimentalAutoDetectBinPacking",
                    Style.ExperimentalAutoDetectBinPacking);
     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
+    IO.mapOptional("IndentWrappedFunctionNames",
+                   Style.IndentWrappedFunctionNames);
+    IO.mapOptional("IndentFunctionDeclarationAfterType",
+                   Style.IndentWrappedFunctionNames);
     IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
     IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
                    Style.KeepEmptyLinesAtTheStartOfBlocks);
@@ -193,7 +211,7 @@
     IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
     IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
                    Style.PenaltyReturnTypeOnItsOwnLine);
-    IO.mapOptional("PointerBindsToType", Style.PointerBindsToType);
+    IO.mapOptional("PointerAlignment", Style.PointerAlignment);
     IO.mapOptional("SpacesBeforeTrailingComments",
                    Style.SpacesBeforeTrailingComments);
     IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
@@ -202,8 +220,6 @@
     IO.mapOptional("TabWidth", Style.TabWidth);
     IO.mapOptional("UseTab", Style.UseTab);
     IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
-    IO.mapOptional("IndentFunctionDeclarationAfterType",
-                   Style.IndentFunctionDeclarationAfterType);
     IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
     IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
     IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses);
@@ -221,6 +237,8 @@
     if (!IO.outputting()) {
       IO.mapOptional("SpaceAfterControlStatementKeyword",
                      Style.SpaceBeforeParens);
+      IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
+      IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
     }
     IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
     IO.mapOptional("DisableFormat", Style.DisableFormat);
@@ -258,6 +276,30 @@
 namespace clang {
 namespace format {
 
+const std::error_category &getParseCategory() {
+  static ParseErrorCategory C;
+  return C;
+}
+std::error_code make_error_code(ParseError e) {
+  return std::error_code(static_cast<int>(e), getParseCategory());
+}
+
+const char *ParseErrorCategory::name() const LLVM_NOEXCEPT {
+  return "clang-format.parse_error";
+}
+
+std::string ParseErrorCategory::message(int EV) const {
+  switch (static_cast<ParseError>(EV)) {
+  case ParseError::Success:
+    return "Success";
+  case ParseError::Error:
+    return "Invalid argument";
+  case ParseError::Unsuitable:
+    return "Unsuitable";
+  }
+  llvm_unreachable("unexpected parse error");
+}
+
 FormatStyle getLLVMStyle() {
   FormatStyle LLVMStyle;
   LLVMStyle.Language = FormatStyle::LK_Cpp;
@@ -282,13 +324,13 @@
   LLVMStyle.ConstructorInitializerIndentWidth = 4;
   LLVMStyle.ContinuationIndentWidth = 4;
   LLVMStyle.Cpp11BracedListStyle = true;
-  LLVMStyle.DerivePointerBinding = false;
+  LLVMStyle.DerivePointerAlignment = false;
   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
   LLVMStyle.ForEachMacros.push_back("foreach");
   LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
   LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
   LLVMStyle.IndentCaseLabels = false;
-  LLVMStyle.IndentFunctionDeclarationAfterType = false;
+  LLVMStyle.IndentWrappedFunctionNames = false;
   LLVMStyle.IndentWidth = 2;
   LLVMStyle.TabWidth = 8;
   LLVMStyle.MaxEmptyLinesToKeep = 1;
@@ -296,7 +338,7 @@
   LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
   LLVMStyle.ObjCSpaceAfterProperty = false;
   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
-  LLVMStyle.PointerBindsToType = false;
+  LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
   LLVMStyle.SpacesBeforeTrailingComments = 1;
   LLVMStyle.Standard = FormatStyle::LS_Cpp11;
   LLVMStyle.UseTab = FormatStyle::UT_Never;
@@ -331,13 +373,12 @@
   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
   GoogleStyle.AlwaysBreakTemplateDeclarations = true;
   GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
-  GoogleStyle.DerivePointerBinding = true;
+  GoogleStyle.DerivePointerAlignment = true;
   GoogleStyle.IndentCaseLabels = true;
-  GoogleStyle.IndentFunctionDeclarationAfterType = true;
   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
   GoogleStyle.ObjCSpaceAfterProperty = false;
   GoogleStyle.ObjCSpaceBeforeProtocolList = false;
-  GoogleStyle.PointerBindsToType = true;
+  GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
   GoogleStyle.SpacesBeforeTrailingComments = 2;
   GoogleStyle.Standard = FormatStyle::LS_Auto;
 
@@ -363,7 +404,7 @@
   ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
   ChromiumStyle.AllowShortLoopsOnASingleLine = false;
   ChromiumStyle.BinPackParameters = false;
-  ChromiumStyle.DerivePointerBinding = false;
+  ChromiumStyle.DerivePointerAlignment = false;
   ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
   return ChromiumStyle;
 }
@@ -373,12 +414,12 @@
   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
   MozillaStyle.Cpp11BracedListStyle = false;
   MozillaStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
-  MozillaStyle.DerivePointerBinding = true;
+  MozillaStyle.DerivePointerAlignment = true;
   MozillaStyle.IndentCaseLabels = true;
   MozillaStyle.ObjCSpaceAfterProperty = true;
   MozillaStyle.ObjCSpaceBeforeProtocolList = false;
   MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
-  MozillaStyle.PointerBindsToType = true;
+  MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
   MozillaStyle.Standard = FormatStyle::LS_Cpp03;
   return MozillaStyle;
 }
@@ -395,7 +436,7 @@
   Style.IndentWidth = 4;
   Style.NamespaceIndentation = FormatStyle::NI_Inner;
   Style.ObjCSpaceAfterProperty = true;
-  Style.PointerBindsToType = true;
+  Style.PointerAlignment = FormatStyle::PAS_Left;
   Style.Standard = FormatStyle::LS_Cpp03;
   return Style;
 }
@@ -442,12 +483,12 @@
   return true;
 }
 
-llvm::error_code parseConfiguration(StringRef Text, FormatStyle *Style) {
+std::error_code parseConfiguration(StringRef Text, FormatStyle *Style) {
   assert(Style);
   FormatStyle::LanguageKind Language = Style->Language;
   assert(Language != FormatStyle::LK_None);
   if (Text.trim().empty())
-    return llvm::make_error_code(llvm::errc::invalid_argument);
+    return make_error_code(ParseError::Error);
 
   std::vector<FormatStyle> Styles;
   llvm::yaml::Input Input(Text);
@@ -463,14 +504,14 @@
   for (unsigned i = 0; i < Styles.size(); ++i) {
     // Ensures that only the first configuration can skip the Language option.
     if (Styles[i].Language == FormatStyle::LK_None && i != 0)
-      return llvm::make_error_code(llvm::errc::invalid_argument);
+      return make_error_code(ParseError::Error);
     // Ensure that each language is configured at most once.
     for (unsigned j = 0; j < i; ++j) {
       if (Styles[i].Language == Styles[j].Language) {
         DEBUG(llvm::dbgs()
               << "Duplicate languages in the config file on positions " << j
               << " and " << i << "\n");
-        return llvm::make_error_code(llvm::errc::invalid_argument);
+        return make_error_code(ParseError::Error);
       }
     }
   }
@@ -482,10 +523,10 @@
         Styles[i].Language == FormatStyle::LK_None) {
       *Style = Styles[i];
       Style->Language = Language;
-      return llvm::error_code::success();
+      return make_error_code(ParseError::Success);
     }
   }
-  return llvm::make_error_code(llvm::errc::not_supported);
+  return make_error_code(ParseError::Unsuitable);
 }
 
 std::string configurationAsText(const FormatStyle &Style) {
@@ -1164,7 +1205,8 @@
       return true;
 
     if (NewLine) {
-      int AdditionalIndent = 0;
+      int AdditionalIndent =
+          State.FirstIndent - State.Line->Level * Style.IndentWidth;
       if (State.Stack.size() < 2 ||
           !State.Stack[State.Stack.size() - 2].JSFunctionInlined) {
         AdditionalIndent = State.Stack.back().Indent -
@@ -1881,11 +1923,11 @@
         Tok = Tok->Next;
       }
     }
-    if (Style.DerivePointerBinding) {
+    if (Style.DerivePointerAlignment) {
       if (CountBoundToType > CountBoundToVariable)
-        Style.PointerBindsToType = true;
+        Style.PointerAlignment = FormatStyle::PAS_Left;
       else if (CountBoundToType < CountBoundToVariable)
-        Style.PointerBindsToType = false;
+        Style.PointerAlignment = FormatStyle::PAS_Right;
     }
     if (Style.Standard == FormatStyle::LS_Auto) {
       Style.Standard = HasCpp03IncompatibleFormat ? FormatStyle::LS_Cpp11
@@ -2001,7 +2043,7 @@
 
   if (StyleName.startswith("{")) {
     // Parse YAML/JSON style from the command line.
-    if (llvm::error_code ec = parseConfiguration(StyleName, &Style)) {
+    if (std::error_code ec = parseConfiguration(StyleName, &Style)) {
       llvm::errs() << "Error parsing -style: " << ec.message() << ", using "
                    << FallbackStyle << " style\n";
     }
@@ -2041,14 +2083,15 @@
     }
 
     if (IsFile) {
-      std::unique_ptr<llvm::MemoryBuffer> Text;
-      if (llvm::error_code ec =
-              llvm::MemoryBuffer::getFile(ConfigFile.c_str(), Text)) {
-        llvm::errs() << ec.message() << "\n";
+      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
+          llvm::MemoryBuffer::getFile(ConfigFile.c_str());
+      if (std::error_code EC = Text.getError()) {
+        llvm::errs() << EC.message() << "\n";
         break;
       }
-      if (llvm::error_code ec = parseConfiguration(Text->getBuffer(), &Style)) {
-        if (ec == llvm::errc::not_supported) {
+      if (std::error_code ec =
+              parseConfiguration(Text.get()->getBuffer(), &Style)) {
+        if (ec == ParseError::Unsuitable) {
           if (!UnsuitableConfigFiles.empty())
             UnsuitableConfigFiles.append(", ");
           UnsuitableConfigFiles.append(ConfigFile);
diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h
index f2bba32..c376c50 100644
--- a/lib/Format/FormatToken.h
+++ b/lib/Format/FormatToken.h
@@ -40,6 +40,7 @@
   TT_CtorInitializerComma,
   TT_DesignatedInitializerPeriod,
   TT_DictLiteral,
+  TT_FunctionDeclarationName,
   TT_FunctionLBrace,
   TT_FunctionTypeLParen,
   TT_ImplicitStringLiteral,
@@ -54,13 +55,13 @@
   TT_ObjCMethodExpr,
   TT_ObjCMethodSpecifier,
   TT_ObjCProperty,
-  TT_ObjCSelectorName,
   TT_OverloadedOperator,
   TT_OverloadedOperatorLParen,
   TT_PointerOrReference,
   TT_PureVirtualSpecifier,
   TT_RangeBasedForLoopColon,
   TT_RegexLiteral,
+  TT_SelectorName,
   TT_StartOfName,
   TT_TemplateCloser,
   TT_TemplateOpener,
@@ -103,9 +104,10 @@
         IsFirst(false), MustBreakBefore(false), IsUnterminatedLiteral(false),
         BlockKind(BK_Unknown), Type(TT_Unknown), SpacesRequiredBefore(0),
         CanBreakBefore(false), ClosesTemplateDeclaration(false),
-        ParameterCount(0), PackingKind(PPK_Inconclusive), TotalLength(0),
-        UnbreakableTailLength(0), BindingStrength(0), NestingLevel(0),
-        SplitPenalty(0), LongestObjCSelectorName(0), FakeRParens(0),
+        ParameterCount(0), BlockParameterCount(0),
+        PackingKind(PPK_Inconclusive), TotalLength(0), UnbreakableTailLength(0),
+        BindingStrength(0), NestingLevel(0), SplitPenalty(0),
+        LongestObjCSelectorName(0), FakeRParens(0),
         StartsBinaryExpression(false), EndsBinaryExpression(false),
         OperatorIndex(0), LastOperator(false),
         PartOfMultiVariableDeclStmt(false), IsForEachMacro(false),
@@ -191,6 +193,10 @@
   /// the number of commas.
   unsigned ParameterCount;
 
+  /// \brief Number of parameters that are nested blocks,
+  /// if this is "(", "[" or "<".
+  unsigned BlockParameterCount;
+
   /// \brief A token can have a special role that can carry extra information
   /// about the token's formatting.
   std::unique_ptr<TokenRole> Role;
@@ -318,7 +324,7 @@
 
   /// \brief Returns \c true if this is a "." or "->" accessing a member.
   bool isMemberAccess() const {
-    return isOneOf(tok::arrow, tok::period) &&
+    return isOneOf(tok::arrow, tok::period, tok::arrowstar) &&
            Type != TT_DesignatedInitializerPeriod;
   }
 
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 3fea52b..afa9840 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -164,6 +164,8 @@
           CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
                                                     tok::coloncolon))
         MightBeFunctionType = true;
+      if (CurrentToken->Previous->Type == TT_BinaryOperator)
+        Contexts.back().IsExpression = true;
       if (CurrentToken->is(tok::r_paren)) {
         if (MightBeFunctionType && CurrentToken->Next &&
             (CurrentToken->Next->is(tok::l_paren) ||
@@ -198,7 +200,6 @@
         return false;
       else if (CurrentToken->is(tok::l_brace))
         Left->Type = TT_Unknown; // Not TT_ObjCBlockLParen
-      updateParameterCount(Left, CurrentToken);
       if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
           !CurrentToken->Next->HasUnescapedNewline &&
           !CurrentToken->Next->isTrailingComment())
@@ -206,8 +207,10 @@
       if (CurrentToken->isOneOf(tok::kw_const, tok::kw_auto) ||
           CurrentToken->isSimpleTypeSpecifier())
         Contexts.back().IsExpression = false;
+      FormatToken *Tok = CurrentToken;
       if (!consumeToken())
         return false;
+      updateParameterCount(Left, Tok);
       if (CurrentToken && CurrentToken->HasUnescapedNewline)
         HasMultipleLines = true;
     }
@@ -266,7 +269,7 @@
         if (Contexts.back().FirstObjCSelectorName) {
           Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
               Contexts.back().LongestObjCSelectorName;
-          if (Contexts.back().NumBlockParameters > 1)
+          if (Left->BlockParameterCount > 1)
             Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
         }
         next();
@@ -281,9 +284,10 @@
           (Left->Type == TT_ArraySubscriptLSquare ||
            (Left->Type == TT_ObjCMethodExpr && !ColonFound)))
         Left->Type = TT_ArrayInitializerLSquare;
-      updateParameterCount(Left, CurrentToken);
+      FormatToken* Tok = CurrentToken;
       if (!consumeToken())
         return false;
+      updateParameterCount(Left, Tok);
     }
     return false;
   }
@@ -312,18 +316,25 @@
           return false;
         updateParameterCount(Left, CurrentToken);
         if (CurrentToken->is(tok::colon) &&
-            Style.Language != FormatStyle::LK_Proto)
+            Style.Language != FormatStyle::LK_Proto) {
+          if (CurrentToken->getPreviousNonComment()->is(tok::identifier))
+            CurrentToken->getPreviousNonComment()->Type = TT_SelectorName;
           Left->Type = TT_DictLiteral;
+        }
         if (!consumeToken())
           return false;
       }
     }
-    // No closing "}" found, this probably starts a definition.
-    Line.StartsDefinition = true;
     return true;
   }
 
   void updateParameterCount(FormatToken *Left, FormatToken *Current) {
+    if (Current->Type == TT_LambdaLSquare ||
+        (Current->is(tok::caret) && Current->Type == TT_UnaryOperator) ||
+        (Style.Language == FormatStyle::LK_JavaScript &&
+         Current->TokenText == "function")) {
+      ++Left->BlockParameterCount;
+    }
     if (Current->is(tok::comma)) {
       ++Left->ParameterCount;
       if (!Left->Role)
@@ -381,7 +392,7 @@
       } else if (Contexts.back().ColonIsObjCMethodExpr ||
                  Line.First->Type == TT_ObjCMethodSpecifier) {
         Tok->Type = TT_ObjCMethodExpr;
-        Tok->Previous->Type = TT_ObjCSelectorName;
+        Tok->Previous->Type = TT_SelectorName;
         if (Tok->Previous->ColumnWidth >
             Contexts.back().LongestObjCSelectorName) {
           Contexts.back().LongestObjCSelectorName = Tok->Previous->ColumnWidth;
@@ -392,7 +403,8 @@
         Tok->Type = TT_RangeBasedForLoopColon;
       } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
         Tok->Type = TT_BitFieldColon;
-      } else if (Contexts.size() == 1 && Line.First->isNot(tok::kw_enum)) {
+      } else if (Contexts.size() == 1 &&
+                 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
         Tok->Type = TT_InheritanceColon;
       } else if (Contexts.back().ContextKind == tok::l_paren) {
         Tok->Type = TT_InlineASMColon;
@@ -638,17 +650,16 @@
     Context(tok::TokenKind ContextKind, unsigned BindingStrength,
             bool IsExpression)
         : ContextKind(ContextKind), BindingStrength(BindingStrength),
-          LongestObjCSelectorName(0), NumBlockParameters(0),
-          ColonIsForRangeExpr(false), ColonIsDictLiteral(false),
-          ColonIsObjCMethodExpr(false), FirstObjCSelectorName(nullptr),
-          FirstStartOfName(nullptr), IsExpression(IsExpression),
-          CanBeExpression(true), InTemplateArgument(false),
-          InCtorInitializer(false), CaretFound(false), IsForEachMacro(false) {}
+          LongestObjCSelectorName(0), ColonIsForRangeExpr(false),
+          ColonIsDictLiteral(false), ColonIsObjCMethodExpr(false),
+          FirstObjCSelectorName(nullptr), FirstStartOfName(nullptr),
+          IsExpression(IsExpression), CanBeExpression(true),
+          InTemplateArgument(false), InCtorInitializer(false),
+          CaretFound(false), IsForEachMacro(false) {}
 
     tok::TokenKind ContextKind;
     unsigned BindingStrength;
     unsigned LongestObjCSelectorName;
-    unsigned NumBlockParameters;
     bool ColonIsForRangeExpr;
     bool ColonIsDictLiteral;
     bool ColonIsObjCMethodExpr;
@@ -741,10 +752,8 @@
                                   Contexts.back().InTemplateArgument);
       } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
         Current.Type = determinePlusMinusCaretUsage(Current);
-        if (Current.Type == TT_UnaryOperator && Current.is(tok::caret)) {
-          ++Contexts.back().NumBlockParameters;
+        if (Current.Type == TT_UnaryOperator && Current.is(tok::caret))
           Contexts.back().CaretFound = true;
-        }
       } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
         Current.Type = determineIncrementUsage(Current);
       } else if (Current.is(tok::exclaim)) {
@@ -829,7 +838,7 @@
 
   /// \brief Determine whether ')' is ending a cast.
   bool rParenEndsCast(const FormatToken &Tok) {
-    FormatToken *LeftOfParens = NULL;
+    FormatToken *LeftOfParens = nullptr;
     if (Tok.MatchingParen)
       LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
     bool IsCast = false;
@@ -852,8 +861,9 @@
       IsCast = true;
     // If there is an identifier after the (), it is likely a cast, unless
     // there is also an identifier before the ().
-    else if (LeftOfParens && (LeftOfParens->Tok.getIdentifierInfo() == NULL ||
-                              LeftOfParens->is(tok::kw_return)) &&
+    else if (LeftOfParens &&
+             (LeftOfParens->Tok.getIdentifierInfo() == nullptr ||
+              LeftOfParens->is(tok::kw_return)) &&
              LeftOfParens->Type != TT_OverloadedOperator &&
              LeftOfParens->isNot(tok::at) &&
              LeftOfParens->Type != TT_TemplateCloser && Tok.Next) {
@@ -891,7 +901,7 @@
       return TT_UnaryOperator;
 
     const FormatToken *NextToken = Tok.getNextNonComment();
-    if (!NextToken)
+    if (!NextToken || NextToken->is(tok::l_brace))
       return TT_Unknown;
 
     if (PrevToken->is(tok::coloncolon) ||
@@ -908,10 +918,13 @@
 
     if (NextToken->is(tok::l_square) && NextToken->Type != TT_LambdaLSquare)
       return TT_PointerOrReference;
+    if (NextToken->is(tok::kw_operator))
+      return TT_PointerOrReference;
 
     if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen &&
         PrevToken->MatchingParen->Previous &&
-        PrevToken->MatchingParen->Previous->is(tok::kw_typeof))
+        PrevToken->MatchingParen->Previous->isOneOf(tok::kw_typeof,
+                                                    tok::kw_decltype))
       return TT_PointerOrReference;
 
     if (PrevToken->Tok.isLiteral() ||
@@ -926,6 +939,12 @@
         (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
       return TT_BinaryOperator;
 
+    // This catches some cases where evaluation order is used as control flow:
+    //   aaa && aaa->f();
+    const FormatToken *NextNextToken = NextToken->getNextNonComment();
+    if (NextNextToken && NextNextToken->is(tok::arrow))
+      return TT_BinaryOperator;
+
     // It is very unlikely that we are going to find a pointer or reference type
     // definition on the RHS of an assignment.
     if (IsExpression)
@@ -993,7 +1012,8 @@
     // expression.
     while (Current &&
            (Current->is(tok::kw_return) ||
-            (Current->is(tok::colon) && Current->Type == TT_ObjCMethodExpr)))
+            (Current->is(tok::colon) && (Current->Type == TT_ObjCMethodExpr ||
+                                         Current->Type == TT_DictLiteral))))
       next();
 
     if (!Current || Precedence > PrecedenceArrowAndPeriod)
@@ -1022,7 +1042,7 @@
 
       int CurrentPrecedence = getCurrentPrecedence();
 
-      if (Current && Current->Type == TT_ObjCSelectorName &&
+      if (Current && Current->Type == TT_SelectorName &&
           Precedence == CurrentPrecedence) {
         if (LatestOperator)
           addFakeParenthesis(Start, prec::Level(Precedence));
@@ -1073,7 +1093,7 @@
       if (Current->Type == TT_ConditionalExpr)
         return prec::Conditional;
       else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon ||
-               Current->Type == TT_ObjCSelectorName)
+               Current->Type == TT_SelectorName)
         return 0;
       else if (Current->Type == TT_RangeBasedForLoopColon)
         return prec::Comma;
@@ -1179,6 +1199,43 @@
   Line.First->CanBreakBefore = Line.First->MustBreakBefore;
 }
 
+// This function heuristically determines whether 'Current' starts the name of a
+// function declaration.
+static bool isFunctionDeclarationName(const FormatToken &Current) {
+  if (Current.Type != TT_StartOfName ||
+      Current.NestingLevel != 0 ||
+      Current.Previous->Type == TT_StartOfName)
+    return false;
+  const FormatToken *Next = Current.Next;
+  for (; Next; Next = Next->Next) {
+    if (Next->Type == TT_TemplateOpener) {
+      Next = Next->MatchingParen;
+    } else if (Next->is(tok::coloncolon)) {
+      Next = Next->Next;
+      if (!Next || !Next->is(tok::identifier))
+        return false;
+    } else if (Next->is(tok::l_paren)) {
+      break;
+    } else {
+      return false;
+    }
+  }
+  if (!Next)
+    return false;
+  assert(Next->is(tok::l_paren));
+  if (Next->Next == Next->MatchingParen)
+    return true;
+  for (const FormatToken *Tok = Next->Next; Tok != Next->MatchingParen;
+       Tok = Tok->Next) {
+    if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
+        Tok->Type == TT_PointerOrReference || Tok->Type == TT_StartOfName)
+      return true;
+    if (Tok->isOneOf(tok::l_brace, tok::string_literal) || Tok->Tok.isLiteral())
+      return false;
+  }
+  return false;
+}
+
 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
   for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
                                                   E = Line.Children.end();
@@ -1193,6 +1250,8 @@
   FormatToken *Current = Line.First->Next;
   bool InFunctionDecl = Line.MightBeFunctionDecl;
   while (Current) {
+    if (isFunctionDeclarationName(*Current))
+      Current->Type = TT_FunctionDeclarationName;
     if (Current->Type == TT_LineComment) {
       if (Current->Previous->BlockKind == BK_BracedInit &&
           Current->Previous->opensScope())
@@ -1295,10 +1354,11 @@
   if (Right.is(tok::l_square)) {
     if (Style.Language == FormatStyle::LK_Proto)
       return 1;
-    if (Right.Type != TT_ObjCMethodExpr)
-      return 250;
+    if (Right.Type != TT_ObjCMethodExpr && Right.Type != TT_LambdaLSquare)
+      return 500;
   }
-  if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator)) {
+  if (Right.Type == TT_StartOfName ||
+      Right.Type == TT_FunctionDeclarationName || Right.is(tok::kw_operator)) {
     if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
       return 3;
     if (Left.Type == TT_StartOfName)
@@ -1328,8 +1388,8 @@
     return 150;
   }
 
-  if (Right.Type == TT_TrailingAnnotation && Right.Next &&
-      Right.Next->isNot(tok::l_paren)) {
+  if (Right.Type == TT_TrailingAnnotation &&
+      (!Right.Next || Right.Next->isNot(tok::l_paren))) {
     // Generally, breaking before a trailing annotation is bad unless it is
     // function-like. It seems to be especially preferable to keep standard
     // annotations (i.e. "const", "final" and "override") on the same line.
@@ -1345,7 +1405,7 @@
 
   // In Objective-C method expressions, prefer breaking before "param:" over
   // breaking after it.
-  if (Right.Type == TT_ObjCSelectorName)
+  if (Right.Type == TT_SelectorName)
     return 0;
   if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr)
     return Line.MightBeFunctionDecl ? 50 : 500;
@@ -1386,6 +1446,10 @@
                                           const FormatToken &Left,
                                           const FormatToken &Right) {
   if (Style.Language == FormatStyle::LK_Proto) {
+    if (Right.is(tok::period) &&
+        (Left.TokenText == "optional" || Left.TokenText == "required" ||
+         Left.TokenText == "repeated"))
+      return true;
     if (Right.is(tok::l_paren) &&
         (Left.TokenText == "returns" || Left.TokenText == "option"))
       return true;
@@ -1442,14 +1506,14 @@
   if (Right.Type == TT_PointerOrReference)
     return Left.Tok.isLiteral() ||
            ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) &&
-            !Style.PointerBindsToType);
+            Style.PointerAlignment != FormatStyle::PAS_Left);
   if (Right.Type == TT_FunctionTypeLParen && Left.isNot(tok::l_paren) &&
-      (Left.Type != TT_PointerOrReference || Style.PointerBindsToType))
+      (Left.Type != TT_PointerOrReference || Style.PointerAlignment != FormatStyle::PAS_Right))
     return true;
   if (Left.Type == TT_PointerOrReference)
     return Right.Tok.isLiteral() || Right.Type == TT_BlockComment ||
            ((Right.Type != TT_PointerOrReference) &&
-            Right.isNot(tok::l_paren) && Style.PointerBindsToType &&
+            Right.isNot(tok::l_paren) && Style.PointerAlignment != FormatStyle::PAS_Right &&
             Left.Previous &&
             !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon));
   if (Right.is(tok::star) && Left.is(tok::l_paren))
@@ -1492,7 +1556,8 @@
   if (Right.Type == TT_UnaryOperator)
     return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
            (Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr);
-  if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square) ||
+  if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
+                    tok::r_paren) ||
        Left.isSimpleTypeSpecifier()) &&
       Right.is(tok::l_brace) && Right.getNextNonComment() &&
       Right.BlockKind != BK_Block)
@@ -1569,9 +1634,17 @@
   return spaceRequiredBetween(Line, *Tok.Previous, Tok);
 }
 
+// Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
+static bool isAllmanBrace(const FormatToken &Tok) {
+  return Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block &&
+         Tok.Type != TT_ObjCBlockLBrace && Tok.Type != TT_DictLiteral;
+}
+
 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
                                      const FormatToken &Right) {
   const FormatToken &Left = *Right.Previous;
+  if (Right.NewlinesBefore > 1)
+    return true;
   if (Right.is(tok::comment)) {
     return Right.Previous->BlockKind != BK_BracedInit &&
            Right.Previous->Type != TT_CtorInitializerColon &&
@@ -1595,10 +1668,6 @@
              Style.BreakConstructorInitializersBeforeComma &&
              !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) {
     return true;
-  } else if (Right.is(tok::l_brace) && Right.BlockKind == BK_Block &&
-             Right.Type != TT_ObjCBlockLBrace && Right.Type != TT_DictLiteral) {
-    return Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
-           Style.BreakBeforeBraces == FormatStyle::BS_GNU;
   } else if (Right.is(tok::string_literal) &&
              Right.TokenText.startswith("R\"")) {
     // Raw string literals are special wrt. line breaks. The author has made a
@@ -1609,6 +1678,9 @@
              Style.Language == FormatStyle::LK_Proto) {
     // Don't enums onto single lines in protocol buffers.
     return true;
+  } else if (isAllmanBrace(Left) || isAllmanBrace(Right)) {
+    return Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+           Style.BreakBeforeBraces == FormatStyle::BS_GNU;
   }
 
   // If the last token before a '}' is a comma or a comment, the intention is to
@@ -1640,7 +1712,8 @@
     return false;
   if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
     return false;
-  if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator))
+  if (Right.Type == TT_StartOfName ||
+      Right.Type == TT_FunctionDeclarationName || Right.is(tok::kw_operator))
     return true;
   if (Right.isTrailingComment())
     // We rely on MustBreakBefore being set correctly here as we should not
@@ -1655,15 +1728,15 @@
     return Style.BreakBeforeTernaryOperators;
   if (Left.Type == TT_ConditionalExpr || Left.is(tok::question))
     return !Style.BreakBeforeTernaryOperators;
-  if (Right.is(tok::colon) &&
-      (Right.Type == TT_DictLiteral || Right.Type == TT_ObjCMethodExpr))
-    return false;
   if (Right.Type == TT_InheritanceColon)
     return true;
+  if (Right.is(tok::colon) && (Right.Type != TT_CtorInitializerColon &&
+                               Right.Type != TT_InlineASMColon))
+    return false;
   if (Left.is(tok::colon) &&
       (Left.Type == TT_DictLiteral || Left.Type == TT_ObjCMethodExpr))
     return true;
-  if (Right.Type == TT_ObjCSelectorName)
+  if (Right.Type == TT_SelectorName)
     return true;
   if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty)
     return true;
@@ -1728,12 +1801,13 @@
     return true;
   if (Left.Type == TT_ArrayInitializerLSquare)
     return true;
-  return (Left.isBinaryOperator() && Left.isNot(tok::lessless) &&
+  return (Left.isBinaryOperator() &&
+          !Left.isOneOf(tok::arrowstar, tok::lessless) &&
           !Style.BreakBeforeBinaryOperators) ||
          Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
                       tok::kw_class, tok::kw_struct) ||
-         Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon,
-                       tok::l_square, tok::at) ||
+         Right.isMemberAccess() ||
+         Right.isOneOf(tok::lessless, tok::colon, tok::l_square, tok::at) ||
          (Left.is(tok::r_paren) &&
           Right.isOneOf(tok::identifier, tok::kw_const)) ||
          (Left.is(tok::l_paren) && !Right.is(tok::r_paren));
@@ -1746,6 +1820,7 @@
     llvm::errs() << " M=" << Tok->MustBreakBefore
                  << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type
                  << " S=" << Tok->SpacesRequiredBefore
+                 << " B=" << Tok->BlockParameterCount
                  << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName()
                  << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind
                  << " FakeLParens=";
diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h
index 0df70a0..36de010 100644
--- a/lib/Format/TokenAnnotator.h
+++ b/lib/Format/TokenAnnotator.h
@@ -41,8 +41,8 @@
       : First(Line.Tokens.front().Tok), Level(Line.Level),
         InPPDirective(Line.InPPDirective),
         MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
-        StartsDefinition(false), Affected(false),
-        LeadingEmptyLinesAffected(false), ChildrenAffected(false) {
+        Affected(false), LeadingEmptyLinesAffected(false),
+        ChildrenAffected(false) {
     assert(!Line.Tokens.empty());
 
     // Calculate Next and Previous for all tokens. Note that we must overwrite
@@ -86,7 +86,6 @@
   bool InPPDirective;
   bool MustBeDeclaration;
   bool MightBeFunctionDecl;
-  bool StartsDefinition;
 
   /// \c True if this line should be formatted, i.e. intersects directly or
   /// indirectly with one of the input ranges.
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index d0750af..20dd573 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -770,7 +770,10 @@
       return;
     case tok::identifier: {
       StringRef Text = FormatTok->TokenText;
-      if (Style.Language == FormatStyle::LK_JavaScript && Text == "function") {
+      // Parse function literal unless 'function' is the first token in a line
+      // in which case this should be treated as a free-standing function.
+      if (Style.Language == FormatStyle::LK_JavaScript && Text == "function" &&
+          Line->Tokens.size() > 0) {
         tryToParseJSFunction();
         break;
       }
@@ -891,6 +894,8 @@
     if (!FormatTok->isOneOf(tok::identifier, tok::kw_this))
       return false;
     nextToken();
+    if (FormatTok->is(tok::ellipsis))
+      nextToken();
     if (FormatTok->is(tok::comma)) {
       nextToken();
     } else if (FormatTok->is(tok::r_square)) {
@@ -905,6 +910,11 @@
 
 void UnwrappedLineParser::tryToParseJSFunction() {
   nextToken();
+
+  // Consume function name.
+  if (FormatTok->is(tok::identifier))
+      nextToken();
+
   if (FormatTok->isNot(tok::l_paren))
     return;
   nextToken();
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 49487d9..fc44d9f 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -47,7 +47,6 @@
 #include <atomic>
 #include <cstdio>
 #include <cstdlib>
-#include <sys/stat.h>
 using namespace clang;
 
 using llvm::TimeRecord;
@@ -247,14 +246,10 @@
   // perform this operation here because we explicitly request that the
   // compiler instance *not* free these buffers for each invocation of the
   // parser.
-  if (Invocation.getPtr() && OwnsRemappedFileBuffers) {
+  if (Invocation.get() && OwnsRemappedFileBuffers) {
     PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
-    for (PreprocessorOptions::remapped_file_buffer_iterator
-           FB = PPOpts.remapped_file_buffer_begin(),
-           FBEnd = PPOpts.remapped_file_buffer_end();
-         FB != FBEnd;
-         ++FB)
-      delete FB->second;
+    for (const auto &RB : PPOpts.RemappedFileBuffers)
+      delete RB.second;
   }
   
   delete SavedMainFileBuffer;
@@ -504,20 +499,17 @@
   Preprocessor &PP;
   ASTContext &Context;
   LangOptions &LangOpt;
-  IntrusiveRefCntPtr<TargetOptions> &TargetOpts;
+  std::shared_ptr<TargetOptions> &TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> &Target;
   unsigned &Counter;
 
   bool InitializedLanguage;
 public:
-  ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt, 
-                   IntrusiveRefCntPtr<TargetOptions> &TargetOpts,
-                   IntrusiveRefCntPtr<TargetInfo> &Target,
-                   unsigned &Counter)
-    : PP(PP), Context(Context), LangOpt(LangOpt),
-      TargetOpts(TargetOpts), Target(Target),
-      Counter(Counter),
-      InitializedLanguage(false) {}
+  ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt,
+                   std::shared_ptr<TargetOptions> &TargetOpts,
+                   IntrusiveRefCntPtr<TargetInfo> &Target, unsigned &Counter)
+      : PP(PP), Context(Context), LangOpt(LangOpt), TargetOpts(TargetOpts),
+        Target(Target), Counter(Counter), InitializedLanguage(false) {}
 
   bool ReadLanguageOptions(const LangOptions &LangOpts,
                            bool Complain) override {
@@ -536,10 +528,10 @@
     // If we've already initialized the target, don't do it again.
     if (Target)
       return false;
-    
-    this->TargetOpts = new TargetOptions(TargetOpts);
-    Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(),
-                                          &*this->TargetOpts);
+
+    this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
+    Target =
+        TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts);
 
     updated();
     return false;
@@ -559,7 +551,7 @@
     //
     // FIXME: We shouldn't need to do this, the target should be immutable once
     // created. This complexity should be lifted elsewhere.
-    Target->setForcedLangOptions(LangOpt);
+    Target->adjust(LangOpt);
 
     // Initialize the preprocessor.
     PP.Initialize(*Target);
@@ -656,7 +648,7 @@
 void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags,
                              const char **ArgBegin, const char **ArgEnd,
                              ASTUnit &AST, bool CaptureDiagnostics) {
-  if (!Diags.getPtr()) {
+  if (!Diags.get()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
     DiagnosticConsumer *Client = nullptr;
@@ -685,7 +677,7 @@
     ASTUnitCleanup(AST.get());
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
   ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics);
 
@@ -1058,7 +1050,7 @@
   IntrusiveRefCntPtr<CompilerInvocation>
     CCInvocation(new CompilerInvocation(*Invocation));
 
-  Clang->setInvocation(CCInvocation.getPtr());
+  Clang->setInvocation(CCInvocation.get());
   OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
     
   // Set up diagnostics, capturing any diagnostics that would
@@ -1066,8 +1058,8 @@
   Clang->setDiagnostics(&getDiagnostics());
   
   // Create the target instance.
-  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                   &Clang->getTargetOpts()));
+  Clang->setTarget(TargetInfo::CreateTargetInfo(
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
   if (!Clang->hasTarget()) {
     delete OverrideMainBuffer;
     return true;
@@ -1077,7 +1069,7 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
+  Clang->getTarget().adjust(Clang->getLangOpts());
   
   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
          "Invocation must have exactly one source file!");
@@ -1087,9 +1079,15 @@
          "IR inputs not support here!");
 
   // Configure the various subsystems.
-  LangOpts = &Clang->getLangOpts();
+  LangOpts = Clang->getInvocation().LangOpts;
   FileSystemOpts = Clang->getFileSystemOpts();
-  // Re-use the existing FileManager
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics());
+  if (!VFS) {
+    delete OverrideMainBuffer;
+    return true;
+  }
+  FileMgr = new FileManager(FileSystemOpts, VFS);
   SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
                                 UserFilesAreVolatile);
   TheSema.reset();
@@ -1211,12 +1209,8 @@
   llvm::sys::fs::UniqueID MainFileID;
   if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) {
     // Check whether there is a file-file remapping of the main file
-    for (PreprocessorOptions::remapped_file_iterator
-          M = PreprocessorOpts.remapped_file_begin(),
-          E = PreprocessorOpts.remapped_file_end();
-         M != E;
-         ++M) {
-      std::string MPath(M->first);
+    for (const auto &RF : PreprocessorOpts.RemappedFiles) {
+      std::string MPath(RF.first);
       llvm::sys::fs::UniqueID MID;
       if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
         if (MainFileID == MID) {
@@ -1225,8 +1219,8 @@
             delete Buffer;
             CreatedBuffer = false;
           }
-          
-          Buffer = getBufferForFile(M->second);
+
+          Buffer = getBufferForFile(RF.second);
           if (!Buffer)
             return std::make_pair(nullptr, std::make_pair(0, true));
           CreatedBuffer = true;
@@ -1236,12 +1230,8 @@
     
     // Check whether there is a file-buffer remapping. It supercedes the
     // file-file remapping.
-    for (PreprocessorOptions::remapped_file_buffer_iterator
-           M = PreprocessorOpts.remapped_file_buffer_begin(),
-           E = PreprocessorOpts.remapped_file_buffer_end();
-         M != E;
-         ++M) {
-      std::string MPath(M->first);
+    for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
+      std::string MPath(RB.first);
       llvm::sys::fs::UniqueID MID;
       if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
         if (MainFileID == MID) {
@@ -1250,8 +1240,8 @@
             delete Buffer;
             CreatedBuffer = false;
           }
-          
-          Buffer = const_cast<llvm::MemoryBuffer *>(M->second);
+
+          Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);
         }
       }
     }
@@ -1417,29 +1407,27 @@
       // First, make a record of those files that have been overridden via
       // remapping or unsaved_files.
       llvm::StringMap<PreambleFileHash> OverriddenFiles;
-      for (PreprocessorOptions::remapped_file_iterator
-                R = PreprocessorOpts.remapped_file_begin(),
-             REnd = PreprocessorOpts.remapped_file_end();
-           !AnyFileChanged && R != REnd;
-           ++R) {
+      for (const auto &R : PreprocessorOpts.RemappedFiles) {
+        if (AnyFileChanged)
+          break;
+
         vfs::Status Status;
-        if (FileMgr->getNoncachedStatValue(R->second, Status)) {
+        if (FileMgr->getNoncachedStatValue(R.second, Status)) {
           // If we can't stat the file we're remapping to, assume that something
           // horrible happened.
           AnyFileChanged = true;
           break;
         }
 
-        OverriddenFiles[R->first] = PreambleFileHash::createForFile(
+        OverriddenFiles[R.first] = PreambleFileHash::createForFile(
             Status.getSize(), Status.getLastModificationTime().toEpochTime());
       }
-      for (PreprocessorOptions::remapped_file_buffer_iterator
-                R = PreprocessorOpts.remapped_file_buffer_begin(),
-             REnd = PreprocessorOpts.remapped_file_buffer_end();
-           !AnyFileChanged && R != REnd;
-           ++R) {
-        OverriddenFiles[R->first] =
-            PreambleFileHash::createForMemoryBuffer(R->second);
+
+      for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
+        if (AnyFileChanged)
+          break;
+        OverriddenFiles[RB.first] =
+            PreambleFileHash::createForMemoryBuffer(RB.second);
       }
        
       // Check whether anything has changed.
@@ -1559,14 +1547,13 @@
   Clang->setDiagnostics(&getDiagnostics());
   
   // Create the target instance.
-  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                                                &Clang->getTargetOpts()));
+  Clang->setTarget(TargetInfo::CreateTargetInfo(
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
   if (!Clang->hasTarget()) {
     llvm::sys::fs::remove(FrontendOpts.OutputFile);
     Preamble.clear();
     PreambleRebuildCounter = DefaultPreambleRebuildInterval;
-    PreprocessorOpts.eraseRemappedFile(
-                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+    PreprocessorOpts.RemappedFileBuffers.pop_back();
     return nullptr;
   }
   
@@ -1574,7 +1561,7 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
+  Clang->getTarget().adjust(Clang->getLangOpts());
   
   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
          "Invocation must have exactly one source file!");
@@ -1603,14 +1590,16 @@
   Clang->setSourceManager(new SourceManager(getDiagnostics(),
                                             Clang->getFileManager()));
 
+  auto PreambleDepCollector = std::make_shared<DependencyCollector>();
+  Clang->addDependencyCollector(PreambleDepCollector);
+
   std::unique_ptr<PrecompilePreambleAction> Act;
   Act.reset(new PrecompilePreambleAction(*this));
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
     llvm::sys::fs::remove(FrontendOpts.OutputFile);
     Preamble.clear();
     PreambleRebuildCounter = DefaultPreambleRebuildInterval;
-    PreprocessorOpts.eraseRemappedFile(
-                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+    PreprocessorOpts.RemappedFileBuffers.pop_back();
     return nullptr;
   }
   
@@ -1638,8 +1627,7 @@
     Preamble.clear();
     TopLevelDeclsInPreamble.clear();
     PreambleRebuildCounter = DefaultPreambleRebuildInterval;
-    PreprocessorOpts.eraseRemappedFile(
-                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+    PreprocessorOpts.RemappedFileBuffers.pop_back();
     return nullptr;
   }
   
@@ -1651,33 +1639,23 @@
   // so we can verify whether they have changed or not.
   FilesInPreamble.clear();
   SourceManager &SourceMgr = Clang->getSourceManager();
-  const llvm::MemoryBuffer *MainFileBuffer
-    = SourceMgr.getBuffer(SourceMgr.getMainFileID());
-  for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(),
-                                     FEnd = SourceMgr.fileinfo_end();
-       F != FEnd;
-       ++F) {
-    const FileEntry *File = F->second->OrigEntry;
-    if (!File)
+  for (auto &Filename : PreambleDepCollector->getDependencies()) {
+    const FileEntry *File = Clang->getFileManager().getFile(Filename);
+    if (!File || File == SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()))
       continue;
-    const llvm::MemoryBuffer *Buffer = F->second->getRawBuffer();
-    if (Buffer == MainFileBuffer)
-      continue;
-
     if (time_t ModTime = File->getModificationTime()) {
       FilesInPreamble[File->getName()] = PreambleFileHash::createForFile(
-          F->second->getSize(), ModTime);
+          File->getSize(), ModTime);
     } else {
-      assert(F->second->getSize() == Buffer->getBufferSize());
+      llvm::MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File);
       FilesInPreamble[File->getName()] =
           PreambleFileHash::createForMemoryBuffer(Buffer);
     }
   }
-  
+
   PreambleRebuildCounter = 1;
-  PreprocessorOpts.eraseRemappedFile(
-                               PreprocessorOpts.remapped_file_buffer_end() - 1);
-  
+  PreprocessorOpts.RemappedFileBuffers.pop_back();
+
   // If the hash of top-level entities differs from the hash of the top-level
   // entities the last time we rebuilt the preamble, clear out the completion
   // cache.
@@ -1709,7 +1687,7 @@
   // Steal the created target, context, and preprocessor if they have been
   // created.
   assert(CI.hasInvocation() && "missing invocation");
-  LangOpts = CI.getInvocation().getLangOpts();
+  LangOpts = CI.getInvocation().LangOpts;
   TheSema.reset(CI.takeSema());
   Consumer.reset(CI.takeASTConsumer());
   if (CI.hasASTContext())
@@ -1810,7 +1788,7 @@
     ASTUnitCleanup(OwnAST.get());
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
   // We'll manage file buffers ourselves.
   CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
@@ -1832,8 +1810,8 @@
   Clang->setDiagnostics(&AST->getDiagnostics());
   
   // Create the target instance.
-  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                                                &Clang->getTargetOpts()));
+  Clang->setTarget(TargetInfo::CreateTargetInfo(
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
   if (!Clang->hasTarget())
     return nullptr;
 
@@ -1841,7 +1819,7 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
+  Clang->getTarget().adjust(Clang->getLangOpts());
   
   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
          "Invocation must have exactly one source file!");
@@ -1966,7 +1944,7 @@
     ASTUnitCleanup(AST.get());
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
   if (AST->LoadFromCompilerInvocation(PrecompilePreamble))
     return nullptr;
@@ -1983,7 +1961,7 @@
     bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies,
     bool UserFilesAreVolatile, bool ForSerialization,
     std::unique_ptr<ASTUnit> *ErrAST) {
-  if (!Diags.getPtr()) {
+  if (!Diags.get()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
     Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
@@ -2073,13 +2051,9 @@
 
   // Remap files.
   PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
-  for (PreprocessorOptions::remapped_file_buffer_iterator 
-         R = PPOpts.remapped_file_buffer_begin(),
-         REnd = PPOpts.remapped_file_buffer_end();
-       R != REnd; 
-       ++R) {
-    delete R->second;
-  }
+  for (const auto &RB : PPOpts.RemappedFileBuffers)
+    delete RB.second;
+
   Invocation->getPreprocessorOpts().clearRemappedFiles();
   for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I) {
     Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
@@ -2409,8 +2383,8 @@
   ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts());
   
   // Create the target instance.
-  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                                                &Clang->getTargetOpts()));
+  Clang->setTarget(TargetInfo::CreateTargetInfo(
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
   if (!Clang->hasTarget()) {
     Clang->setInvocation(nullptr);
     return;
@@ -2420,7 +2394,7 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
+  Clang->getTarget().adjust(Clang->getLangOpts());
   
   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
          "Invocation must have exactly one source file!");
diff --git a/lib/Frontend/Android.mk b/lib/Frontend/Android.mk
index ec6489a..e93ba21 100644
--- a/lib/Frontend/Android.mk
+++ b/lib/Frontend/Android.mk
@@ -44,6 +44,7 @@
   LangStandards.cpp \
   LayoutOverrideSource.cpp \
   LogDiagnosticPrinter.cpp \
+  ModuleDependencyCollector.cpp \
   MultiplexConsumer.cpp \
   PrintPreprocessedOutput.cpp \
   SerializedDiagnosticPrinter.cpp \
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index b67e0ae..3fa7a2c 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -25,6 +25,7 @@
   LangStandards.cpp
   LayoutOverrideSource.cpp
   LogDiagnosticPrinter.cpp
+  ModuleDependencyCollector.cpp
   MultiplexConsumer.cpp
   PrintPreprocessedOutput.cpp
   SerializedDiagnosticPrinter.cpp
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index d30196d..14f7027 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -540,7 +540,8 @@
   ~StatListener() {}
 
   LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                       vfs::File **F, vfs::FileSystem &FS) override {
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override {
     LookupResult Result = statChained(Path, Data, isFile, F, FS);
 
     if (Result == CacheMissing) // Failed 'stat'.
diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp
index 6dc3fd4..e6e73ac 100644
--- a/lib/Frontend/ChainedIncludesSource.cpp
+++ b/lib/Frontend/ChainedIncludesSource.cpp
@@ -12,7 +12,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Frontend/ChainedIncludesSource.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -25,6 +24,54 @@
 
 using namespace clang;
 
+namespace {
+class ChainedIncludesSource : public ExternalSemaSource {
+public:
+  virtual ~ChainedIncludesSource();
+
+  ExternalSemaSource &getFinalReader() const { return *FinalReader; }
+
+  std::vector<CompilerInstance *> CIs;
+  IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
+
+protected:
+  //===----------------------------------------------------------------------===//
+  // ExternalASTSource interface.
+  //===----------------------------------------------------------------------===//
+
+  Decl *GetExternalDecl(uint32_t ID) override;
+  Selector GetExternalSelector(uint32_t ID) override;
+  uint32_t GetNumExternalSelectors() override;
+  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
+  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
+  bool FindExternalVisibleDeclsByName(const DeclContext *DC,
+                                      DeclarationName Name) override;
+  ExternalLoadResult
+  FindExternalLexicalDecls(const DeclContext *DC,
+                           bool (*isKindWeWant)(Decl::Kind),
+                           SmallVectorImpl<Decl *> &Result) override;
+  void CompleteType(TagDecl *Tag) override;
+  void CompleteType(ObjCInterfaceDecl *Class) override;
+  void StartedDeserializing() override;
+  void FinishedDeserializing() override;
+  void StartTranslationUnit(ASTConsumer *Consumer) override;
+  void PrintStats() override;
+
+  /// Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
+
+  //===----------------------------------------------------------------------===//
+  // ExternalSemaSource interface.
+  //===----------------------------------------------------------------------===//
+
+  void InitializeSema(Sema &S) override;
+  void ForgetSema() override;
+  void ReadMethodPool(Selector Sel) override;
+  bool LookupUnqualified(LookupResult &R, Scope *S) override;
+};
+}
+
 static ASTReader *
 createASTReader(CompilerInstance &CI, StringRef pchFile,
                 SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
@@ -62,8 +109,8 @@
     delete CIs[i];
 }
 
-IntrusiveRefCntPtr<ChainedIncludesSource>
-ChainedIncludesSource::create(CompilerInstance &CI) {
+IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
+    CompilerInstance &CI, IntrusiveRefCntPtr<ExternalSemaSource> &Reader) {
 
   std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes;
   assert(!includes.empty() && "No '-chain-include' in options!");
@@ -99,9 +146,9 @@
 
     std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
     Clang->setInvocation(CInvok.release());
-    Clang->setDiagnostics(Diags.getPtr());
-    Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                                                  &Clang->getTargetOpts()));
+    Clang->setDiagnostics(Diags.get());
+    Clang->setTarget(TargetInfo::CreateTargetInfo(
+        Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
     Clang->createFileManager();
     Clang->createSourceManager(Clang->getFileManager());
     Clang->createPreprocessor(TU_Prefix);
@@ -126,17 +173,14 @@
     } else {
       assert(!serialBufs.empty());
       SmallVector<llvm::MemoryBuffer *, 4> bufs;
-      for (unsigned si = 0, se = serialBufs.size(); si != se; ++si) {
-        bufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
-                             StringRef(serialBufs[si]->getBufferStart(),
-                                             serialBufs[si]->getBufferSize())));
-      }
+      // TODO: Pass through the existing MemoryBuffer instances instead of
+      // allocating new ones.
+      for (auto *SB : serialBufs)
+        bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
       std::string pchName = includes[i-1];
       llvm::raw_string_ostream os(pchName);
       os << ".pch" << i-1;
-      os.flush();
-      
-      serialBufNames.push_back(pchName);
+      serialBufNames.push_back(os.str());
 
       IntrusiveRefCntPtr<ASTReader> Reader;
       Reader = createASTReader(*Clang, pchName, bufs, serialBufNames, 
@@ -151,18 +195,14 @@
       return nullptr;
 
     ParseAST(Clang->getSema());
-    OS.flush();
     Clang->getDiagnosticClient().EndSourceFile();
-    serialBufs.push_back(
-      llvm::MemoryBuffer::getMemBufferCopy(StringRef(serialAST.data(),
-                                                           serialAST.size())));
+    serialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
     source->CIs.push_back(Clang.release());
   }
 
   assert(!serialBufs.empty());
   std::string pchName = includes.back() + ".pch-final";
   serialBufNames.push_back(pchName);
-  IntrusiveRefCntPtr<ASTReader> Reader;
   Reader = createASTReader(CI, pchName, serialBufs, serialBufNames);
   if (!Reader)
     return nullptr;
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index c65d34b..7cea9e4 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -16,6 +16,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
 #include "clang/Frontend/ChainedDiagnosticConsumer.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/FrontendActions.h"
@@ -33,8 +34,8 @@
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/Config/config.h"
 #include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/LockFileManager.h"
@@ -44,8 +45,8 @@
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include <sys/stat.h>
+#include <system_error>
 #include <time.h>
 
 using namespace clang;
@@ -115,6 +116,16 @@
   ModuleManager = Reader;
 }
 
+std::shared_ptr<ModuleDependencyCollector>
+CompilerInstance::getModuleDepCollector() const {
+  return ModuleDepCollector;
+}
+
+void CompilerInstance::setModuleDepCollector(
+    std::shared_ptr<ModuleDependencyCollector> Collector) {
+  ModuleDepCollector = Collector;
+}
+
 // Diagnostics
 static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
                                const CodeGenOptions *CodeGenOpts,
@@ -223,6 +234,56 @@
   SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
 }
 
+// Initialize the remapping of files to alternative contents, e.g.,
+// those specified through other files.
+static void InitializeFileRemapping(DiagnosticsEngine &Diags,
+                                    SourceManager &SourceMgr,
+                                    FileManager &FileMgr,
+                                    const PreprocessorOptions &InitOpts) {
+  // Remap files in the source manager (with buffers).
+  for (const auto &RB : InitOpts.RemappedFileBuffers) {
+    // Create the file entry for the file that we're mapping from.
+    const FileEntry *FromFile =
+        FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0);
+    if (!FromFile) {
+      Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first;
+      if (!InitOpts.RetainRemappedFileBuffers)
+        delete RB.second;
+      continue;
+    }
+
+    // Override the contents of the "from" file with the contents of
+    // the "to" file.
+    SourceMgr.overrideFileContents(FromFile, RB.second,
+                                   InitOpts.RetainRemappedFileBuffers);
+  }
+
+  // Remap files in the source manager (with other files).
+  for (const auto &RF : InitOpts.RemappedFiles) {
+    // Find the file that we're mapping to.
+    const FileEntry *ToFile = FileMgr.getFile(RF.second);
+    if (!ToFile) {
+      Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
+      continue;
+    }
+
+    // Create the file entry for the file that we're mapping from.
+    const FileEntry *FromFile =
+        FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);
+    if (!FromFile) {
+      Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
+      continue;
+    }
+
+    // Override the contents of the "from" file with the contents of
+    // the "to" file.
+    SourceMgr.overrideFileContents(FromFile, ToFile);
+  }
+
+  SourceMgr.setOverridenFilesKeepOriginalName(
+      InitOpts.RemappedFilesKeepOriginalName);
+}
+
 // Preprocessor
 
 void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
@@ -255,7 +316,16 @@
   if (PPOpts.DetailedRecord)
     PP->createPreprocessingRecord();
 
-  InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts());
+  // Apply remappings to the source manager.
+  InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(),
+                          PP->getFileManager(), PPOpts);
+
+  // Predefine macros and configure the preprocessor.
+  InitializePreprocessor(*PP, PPOpts, getFrontendOpts());
+
+  // Initialize the header search object.
+  ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(),
+                           PP->getLangOpts(), PP->getTargetInfo().getTriple());
 
   PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
 
@@ -277,6 +347,14 @@
     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
                              getHeaderSearchOpts().Sysroot);
 
+  for (auto &Listener : DependencyCollectors)
+    Listener->attachToPreprocessor(*PP);
+
+  // If we don't have a collector, but we are collecting module dependencies,
+  // then we're the top level compiler instance and need to create one.
+  if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty())
+    ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
+        DepOpts.ModuleDependencyOutputDir);
 
   // Handle generating header include information, if requested.
   if (DepOpts.ShowHeaderIncludes)
@@ -317,7 +395,7 @@
       AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
       DeserializationListener, OwnDeserializationListener, Preamble,
       getFrontendOpts().UseGlobalModuleIndex);
-  ModuleManager = static_cast<ASTReader*>(Source.getPtr());
+  ModuleManager = static_cast<ASTReader*>(Source.get());
   getASTContext().setExternalSource(Source);
 }
 
@@ -454,8 +532,8 @@
         // If '-working-directory' was passed, the output filename should be
         // relative to that.
         FileMgr->FixupRelativePath(NewOutFile);
-        if (llvm::error_code ec = llvm::sys::fs::rename(it->TempFilename,
-                                                        NewOutFile.str())) {
+        if (std::error_code ec =
+                llvm::sys::fs::rename(it->TempFilename, NewOutFile.str())) {
           getDiagnostics().Report(diag::err_unable_to_rename_temp)
             << it->TempFilename << it->Filename << ec.message();
 
@@ -478,6 +556,12 @@
                           /*UseTemporary=*/true);
 }
 
+llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() {
+  llvm::raw_null_ostream *OS = new llvm::raw_null_ostream();
+  addOutputFile(OutputFile("", "", OS));
+  return OS;
+}
+
 llvm::raw_fd_ostream *
 CompilerInstance::createOutputFile(StringRef OutputPath,
                                    bool Binary, bool RemoveFileOnSignal,
@@ -562,7 +646,7 @@
     TempPath = OutFile;
     TempPath += "-%%%%%%%%";
     int fd;
-    llvm::error_code EC =
+    std::error_code EC =
         llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath);
 
     if (CreateMissingDirectories &&
@@ -658,11 +742,14 @@
     SourceMgr.setMainFileID(
         SourceMgr.createFileID(File, SourceLocation(), Kind));
   } else {
-    std::unique_ptr<llvm::MemoryBuffer> SB;
-    if (llvm::error_code ec = llvm::MemoryBuffer::getSTDIN(SB)) {
-      Diags.Report(diag::err_fe_error_reading_stdin) << ec.message();
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr =
+        llvm::MemoryBuffer::getSTDIN();
+    if (std::error_code EC = SBOrErr.getError()) {
+      Diags.Report(diag::err_fe_error_reading_stdin) << EC.message();
       return false;
     }
+    std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get());
+
     const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
                                                    SB->getBufferSize(), 0);
     SourceMgr.setMainFileID(
@@ -687,7 +774,8 @@
   raw_ostream &OS = llvm::errs();
 
   // Create the target instance.
-  setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), &getTargetOpts()));
+  setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
+                                         getInvocation().TargetOpts));
   if (!hasTarget())
     return false;
 
@@ -695,7 +783,7 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  getTarget().setForcedLangOptions(getLangOpts());
+  getTarget().adjust(getLangOpts());
 
   // rewriter project will change target built-in bool type from its default. 
   if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)
@@ -704,7 +792,7 @@
   // Validate/process some options.
   if (getHeaderSearchOpts().Verbose)
     OS << "clang -cc1 version " CLANG_VERSION_STRING
-       << " based upon " << PACKAGE_STRING
+       << " based upon " << BACKEND_PACKAGE_STRING
        << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
 
   if (getFrontendOpts().ShowTimers)
@@ -844,6 +932,10 @@
   SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(),
     FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
 
+  // If we're collecting module dependencies, we need to share a collector
+  // between all of the module CompilerInstances.
+  Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());
+
   // Get or create the module map that we'll use to build this module.
   std::string InferredModuleMapContent;
   if (const FileEntry *ModuleMapFile =
@@ -858,7 +950,7 @@
     FrontendOpts.Inputs.push_back(
         FrontendInputFile("__inferred_module.map", IK));
 
-    const llvm::MemoryBuffer *ModuleMapBuffer =
+    llvm::MemoryBuffer *ModuleMapBuffer =
         llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
     ModuleMapFile = Instance.getFileManager().getVirtualFile(
         "__inferred_module.map", InferredModuleMapContent.size(), 0);
@@ -889,23 +981,28 @@
   }
 }
 
-static void compileModule(CompilerInstance &ImportingInstance,
-                          SourceLocation ImportLoc,
-                          Module *Module,
-                          StringRef ModuleFileName) {
+static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
+                                 SourceLocation ImportLoc,
+                                 SourceLocation ModuleNameLoc,
+                                 Module *Module,
+                                 StringRef ModuleFileName) {
   // FIXME: have LockFileManager return an error_code so that we can
   // avoid the mkdir when the directory already exists.
   StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
   llvm::sys::fs::create_directories(Dir);
 
   while (1) {
+    unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing;
     llvm::LockFileManager Locked(ModuleFileName);
     switch (Locked) {
     case llvm::LockFileManager::LFS_Error:
-      return;
+      return false;
 
     case llvm::LockFileManager::LFS_Owned:
-      // We're responsible for building the module ourselves. Do so below.
+      // We're responsible for building the module ourselves.
+      // FIXME: if there are errors, don't attempt to load the module.
+      compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
+                        ModuleFileName);
       break;
 
     case llvm::LockFileManager::LFS_Shared:
@@ -913,11 +1010,28 @@
       // finish.
       if (Locked.waitForUnlock() == llvm::LockFileManager::Res_OwnerDied)
         continue; // try again to get the lock.
-      return;
+      ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;
+      break;
     }
 
-    return compileModuleImpl(ImportingInstance, ImportLoc, Module,
-                             ModuleFileName);
+    // Try to read the module file, now that we've compiled it.
+    ASTReader::ASTReadResult ReadResult =
+        ImportingInstance.getModuleManager()->ReadAST(
+            ModuleFileName, serialization::MK_Module, ImportLoc,
+            ModuleLoadCapabilities);
+
+    if (ReadResult == ASTReader::OutOfDate &&
+        Locked == llvm::LockFileManager::LFS_Shared) {
+      // The module may be out of date in the presence of file system races,
+      // or if one of its imports depends on header search paths that are not
+      // consistent with this ImportingInstance.  Try again...
+      continue;
+    } else if (ReadResult == ASTReader::Missing) {
+      ImportingInstance.getDiagnostics().Report(ModuleNameLoc,
+                                                diag::err_module_not_built)
+          << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
+    }
+    return ReadResult == ASTReader::Success;
   }
 }
 
@@ -1045,7 +1159,7 @@
 
   // Walk the entire module cache, looking for unused module files and module
   // indices.
-  llvm::error_code EC;
+  std::error_code EC;
   SmallString<128> ModuleCachePathNative;
   llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative);
   for (llvm::sys::fs::directory_iterator
@@ -1182,6 +1296,12 @@
     if (TheDependencyFileGenerator)
       TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
 
+    if (ModuleDepCollector)
+      ModuleDepCollector->attachToASTReader(*ModuleManager);
+
+    for (auto &Listener : DependencyCollectors)
+      Listener->attachToASTReader(*ModuleManager);
+
     // Try to load the module file.
     unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
     switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module,
@@ -1228,23 +1348,9 @@
         return ModuleLoadResult();
       }
 
-      // Try to compile the module.
-      compileModule(*this, ModuleNameLoc, Module, ModuleFileName);
-
-      // Try to read the module file, now that we've compiled it.
-      ASTReader::ASTReadResult ReadResult
-        = ModuleManager->ReadAST(ModuleFileName,
-                                 serialization::MK_Module, ImportLoc,
-                                 ASTReader::ARR_Missing);
-      if (ReadResult != ASTReader::Success) {
-        if (ReadResult == ASTReader::Missing) {
-          getDiagnostics().Report(ModuleNameLoc,
-                                  Module? diag::err_module_not_built
-                                        : diag::err_module_not_found)
-            << ModuleName
-            << SourceRange(ImportLoc, ModuleNameLoc);
-        }
-
+      // Try to compile and then load the module.
+      if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module,
+                                ModuleFileName)) {
         if (getPreprocessorOpts().FailedModules)
           getPreprocessorOpts().FailedModules->addFailed(ModuleName);
         KnownModules[Path[0].first] = nullptr;
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 2ba9450..3d79ac7 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -20,6 +20,7 @@
 #include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
@@ -33,10 +34,10 @@
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
-#include "llvm/Support/system_error.h"
 #include <atomic>
 #include <memory>
 #include <sys/stat.h>
+#include <system_error>
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -309,6 +310,22 @@
   return "default";
 }
 
+/// \brief Create a new Regex instance out of the string value in \p RpassArg.
+/// It returns a pointer to the newly generated Regex instance.
+static std::shared_ptr<llvm::Regex>
+GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args,
+                                Arg *RpassArg) {
+  StringRef Val = RpassArg->getValue();
+  std::string RegexError;
+  std::shared_ptr<llvm::Regex> Pattern = std::make_shared<llvm::Regex>(Val);
+  if (!Pattern->isValid(RegexError)) {
+    Diags.Report(diag::err_drv_optimization_remark_pattern)
+        << RegexError << RpassArg->getAsString(Args);
+    Pattern.reset();
+  }
+  return Pattern;
+}
+
 static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
                              DiagnosticsEngine &Diags,
                              const TargetOptions &TargetOpts) {
@@ -533,18 +550,31 @@
   }
 
   Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib);
+  bool NeedLocTracking = false;
 
   if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) {
-    StringRef Val = A->getValue();
-    std::string RegexError;
-    Opts.OptimizationRemarkPattern = std::make_shared<llvm::Regex>(Val);
-    if (!Opts.OptimizationRemarkPattern->isValid(RegexError)) {
-      Diags.Report(diag::err_drv_optimization_remark_pattern)
-          << RegexError << A->getAsString(Args);
-      Opts.OptimizationRemarkPattern.reset();
-    }
+    Opts.OptimizationRemarkPattern =
+        GenerateOptimizationRemarkRegex(Diags, Args, A);
+    NeedLocTracking = true;
   }
 
+  if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ)) {
+    Opts.OptimizationRemarkMissedPattern =
+        GenerateOptimizationRemarkRegex(Diags, Args, A);
+    NeedLocTracking = true;
+  }
+
+  if (Arg *A = Args.getLastArg(OPT_Rpass_analysis_EQ)) {
+    Opts.OptimizationRemarkAnalysisPattern =
+        GenerateOptimizationRemarkRegex(Diags, Args, A);
+    NeedLocTracking = true;
+  }
+
+  // If the user requested one of the flags in the -Rpass family, make sure
+  // that the backend tracks source location information.
+  if (NeedLocTracking && Opts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
+    Opts.setDebugInfo(CodeGenOptions::LocTrackingOnly);
+
   return Success;
 }
 
@@ -561,6 +591,8 @@
   Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG);
   Opts.PrintShowIncludes = Args.hasArg(OPT_show_includes);
   Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot);
+  Opts.ModuleDependencyOutputDir =
+      Args.getLastArgValue(OPT_module_dependency_dir);
 }
 
 bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
@@ -1107,6 +1139,7 @@
   Opts.CPlusPlus = Std.isCPlusPlus();
   Opts.CPlusPlus11 = Std.isCPlusPlus11();
   Opts.CPlusPlus1y = Std.isCPlusPlus1y();
+  Opts.CPlusPlus1z = Std.isCPlusPlus1z();
   Opts.Digraphs = Std.hasDigraphs();
   Opts.GNUMode = Std.isGNUMode();
   Opts.GNUInline = !Std.isC99();
@@ -1114,18 +1147,13 @@
   Opts.ImplicitInt = Std.hasImplicitInt();
 
   // Set OpenCL Version.
-  if (LangStd == LangStandard::lang_opencl) {
-    Opts.OpenCL = 1;
+  Opts.OpenCL = LangStd == LangStandard::lang_opencl || IK == IK_OpenCL;
+  if (LangStd == LangStandard::lang_opencl)
     Opts.OpenCLVersion = 100;
-  }
-  else if (LangStd == LangStandard::lang_opencl11) {
-      Opts.OpenCL = 1;
+  else if (LangStd == LangStandard::lang_opencl11)
       Opts.OpenCLVersion = 110;
-  }
-  else if (LangStd == LangStandard::lang_opencl12) {
-    Opts.OpenCL = 1;
+  else if (LangStd == LangStandard::lang_opencl12)
     Opts.OpenCLVersion = 120;
-  }
   
   // OpenCL has some additional defaults.
   if (Opts.OpenCL) {
@@ -1136,8 +1164,7 @@
     Opts.NativeHalfType = 1;
   }
 
-  if (LangStd == LangStandard::lang_cuda)
-    Opts.CUDA = 1;
+  Opts.CUDA = LangStd == LangStandard::lang_cuda || IK == IK_CUDA;
 
   // OpenCL and C++ both have bool, true, false keywords.
   Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
@@ -1153,7 +1180,8 @@
 
   // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
   // is specified, or -std is set to a conforming mode.
-  Opts.Trigraphs = !Opts.GNUMode;
+  // Trigraphs are disabled by default in c++1z onwards.
+  Opts.Trigraphs = !Opts.GNUMode && !Opts.CPlusPlus1z;
 
   Opts.DollarIdents = !Opts.AsmPreprocessor;
 
@@ -1179,6 +1207,60 @@
   return DefaultVisibility;
 }
 
+static unsigned parseMSCVersion(ArgList &Args, DiagnosticsEngine &Diags) {
+  auto Arg = Args.getLastArg(OPT_fmsc_version);
+  if (!Arg)
+    return 0;
+
+  // The MSC versioning scheme involves four versioning components:
+  //  - Major
+  //  - Minor
+  //  - Build
+  //  - Patch
+  //
+  // We accept either the old style (_MSC_VER) value, or a _MSC_FULL_VER value.
+  // Additionally, the value may be provided in the form of a more readable
+  // MM.mm.bbbbb.pp version.
+  //
+  // Unfortunately, due to the bit-width limitations, we cannot currently encode
+  // the value for the patch level.
+
+  StringRef Value = Arg->getValue();
+
+  // parse the compatible old form of _MSC_VER or the newer _MSC_FULL_VER
+  if (Value.find('.') == StringRef::npos) {
+    unsigned Version = 0;
+    if (Value.getAsInteger(10, Version)) {
+      Diags.Report(diag::err_drv_invalid_value)
+        << Arg->getAsString(Args) << Value;
+      return 0;
+    }
+    if (Version < 100)
+      Version = Version * 100;    // major -> major.minor
+    if (Version < 100000)
+      Version = Version * 100000; // major.minor -> major.minor.build
+    return Version;
+  }
+
+  // parse the dot-delimited component version
+  unsigned VC[4] = {0};
+  SmallVector<StringRef, 4> Components;
+
+  Value.split(Components, ".", llvm::array_lengthof(VC));
+  for (unsigned CI = 0,
+                CE = std::min(Components.size(), llvm::array_lengthof(VC));
+       CI < CE; ++CI) {
+    if (Components[CI].getAsInteger(10, VC[CI])) {
+      Diags.Report(diag::err_drv_invalid_value)
+        << Arg->getAsString(Args) << Value;
+      return 0;
+    }
+  }
+
+  // FIXME we cannot encode the patch level
+  return VC[0] * 10000000 + VC[1] * 100000 + VC[2];
+}
+
 static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
                           DiagnosticsEngine &Diags) {
   // FIXME: Cleanup per-file based stuff.
@@ -1348,7 +1430,7 @@
   Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility);
   Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions);
   Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt;
-  Opts.MSCVersion = getLastArgIntValue(Args, OPT_fmsc_version, 0, Diags);
+  Opts.MSCVersion = parseMSCVersion(Args, Diags);
   Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags);
   Opts.Borland = Args.hasArg(OPT_fborland_extensions);
   Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
@@ -1365,6 +1447,7 @@
   Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
 
   Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
+  Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data);
   Opts.Blocks = Args.hasArg(OPT_fblocks);
   Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional);
   Opts.Modules = Args.hasArg(OPT_fmodules);
@@ -1874,14 +1957,16 @@
   //   $sysroot/System/Library/CoreServices/SystemVersion.plist
   // as part of the module hash.
   if (!hsOpts.Sysroot.empty()) {
-    std::unique_ptr<llvm::MemoryBuffer> buffer;
     SmallString<128> systemVersionFile;
     systemVersionFile += hsOpts.Sysroot;
     llvm::sys::path::append(systemVersionFile, "System");
     llvm::sys::path::append(systemVersionFile, "Library");
     llvm::sys::path::append(systemVersionFile, "CoreServices");
     llvm::sys::path::append(systemVersionFile, "SystemVersion.plist");
-    if (!llvm::MemoryBuffer::getFile(systemVersionFile.str(), buffer)) {
+
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
+        llvm::MemoryBuffer::getFile(systemVersionFile.str());
+    if (buffer) {
       code = hash_combine(code, buffer.get()->getBuffer());
 
       struct stat statBuf;
@@ -1948,15 +2033,16 @@
     Overlay(new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
   // earlier vfs files are on the bottom
   for (const std::string &File : CI.getHeaderSearchOpts().VFSOverlayFiles) {
-    std::unique_ptr<llvm::MemoryBuffer> Buffer;
-    if (llvm::errc::success != llvm::MemoryBuffer::getFile(File, Buffer)) {
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
+        llvm::MemoryBuffer::getFile(File);
+    if (!Buffer) {
       Diags.Report(diag::err_missing_vfs_overlay_file) << File;
       return IntrusiveRefCntPtr<vfs::FileSystem>();
     }
 
     IntrusiveRefCntPtr<vfs::FileSystem> FS =
-        vfs::getVFSFromYAML(Buffer.release(), /*DiagHandler*/nullptr);
-    if (!FS.getPtr()) {
+        vfs::getVFSFromYAML(Buffer->release(), /*DiagHandler*/ nullptr);
+    if (!FS.get()) {
       Diags.Report(diag::err_invalid_vfs_overlay) << File;
       return IntrusiveRefCntPtr<vfs::FileSystem>();
     }
diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp
index 45f7aa3..f2f36e4 100644
--- a/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -32,7 +32,7 @@
 CompilerInvocation *
 clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList,
                             IntrusiveRefCntPtr<DiagnosticsEngine> Diags) {
-  if (!Diags.getPtr()) {
+  if (!Diags.get()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
     Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions);
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index e72be89..0b9c0d4 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -29,6 +29,105 @@
 using namespace clang;
 
 namespace {
+struct DepCollectorPPCallbacks : public PPCallbacks {
+  DependencyCollector &DepCollector;
+  SourceManager &SM;
+  DepCollectorPPCallbacks(DependencyCollector &L, SourceManager &SM)
+      : DepCollector(L), SM(SM) { }
+
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override {
+    if (Reason != PPCallbacks::EnterFile)
+      return;
+
+    // Dependency generation really does want to go all the way to the
+    // file entry for a source location to find out what is depended on.
+    // We do not want #line markers to affect dependency generation!
+    const FileEntry *FE =
+        SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(Loc)));
+    if (!FE)
+      return;
+
+    StringRef Filename = FE->getName();
+
+    // Remove leading "./" (or ".//" or "././" etc.)
+    while (Filename.size() > 2 && Filename[0] == '.' &&
+           llvm::sys::path::is_separator(Filename[1])) {
+      Filename = Filename.substr(1);
+      while (llvm::sys::path::is_separator(Filename[0]))
+        Filename = Filename.substr(1);
+    }
+
+    DepCollector.maybeAddDependency(Filename, /*FromModule*/false,
+                                   FileType != SrcMgr::C_User,
+                                   /*IsModuleFile*/false, /*IsMissing*/false);
+  }
+
+  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 (!File)
+      DepCollector.maybeAddDependency(FileName, /*FromModule*/false,
+                                     /*IsSystem*/false, /*IsModuleFile*/false,
+                                     /*IsMissing*/true);
+    // Files that actually exist are handled by FileChanged.
+  }
+
+  void EndOfMainFile() override {
+    DepCollector.finishedMainFile();
+  }
+};
+
+struct DepCollectorASTListener : public ASTReaderListener {
+  DependencyCollector &DepCollector;
+  DepCollectorASTListener(DependencyCollector &L) : DepCollector(L) { }
+  bool needsInputFileVisitation() override { return true; }
+  bool needsSystemInputFileVisitation() override {
+    return DepCollector.needSystemDependencies();
+  }
+  void visitModuleFile(StringRef Filename) override {
+    DepCollector.maybeAddDependency(Filename, /*FromModule*/true,
+                                   /*IsSystem*/false, /*IsModuleFile*/true,
+                                   /*IsMissing*/false);
+  }
+  bool visitInputFile(StringRef Filename, bool IsSystem,
+                      bool IsOverridden) override {
+    if (IsOverridden)
+      return true;
+
+    DepCollector.maybeAddDependency(Filename, /*FromModule*/true, IsSystem,
+                                   /*IsModuleFile*/false, /*IsMissing*/false);
+    return true;
+  }
+};
+} // end anonymous namespace
+
+void DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule,
+                                            bool IsSystem, bool IsModuleFile,
+                                            bool IsMissing) {
+  if (Seen.insert(Filename) &&
+      sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing))
+    Dependencies.push_back(Filename);
+}
+
+bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule,
+                                       bool IsSystem, bool IsModuleFile,
+                                       bool IsMissing) {
+  return Filename != "<built-in>" && (needSystemDependencies() || !IsSystem);
+}
+
+DependencyCollector::~DependencyCollector() { }
+void DependencyCollector::attachToPreprocessor(Preprocessor &PP) {
+  PP.addPPCallbacks(new DepCollectorPPCallbacks(*this, PP.getSourceManager()));
+}
+void DependencyCollector::attachToASTReader(ASTReader &R) {
+  R.addListener(new DepCollectorASTListener(*this));
+}
+
+namespace {
 /// Private implementation for DependencyFileGenerator
 class DFGImpl : public PPCallbacks {
   std::vector<std::string> Files;
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index ce9fc05..cff32b8 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -190,6 +190,12 @@
                  &Diag);
 }
 
+void DiagnosticRenderer::emitBasicNote(StringRef Message) {
+  emitDiagnosticMessage(
+      SourceLocation(), PresumedLoc(), DiagnosticsEngine::Note, Message,
+      ArrayRef<CharSourceRange>(), nullptr, DiagOrStoredDiag());
+}
+
 /// \brief Prints an include stack when appropriate for a particular
 /// diagnostic level and location.
 ///
@@ -506,8 +512,3 @@
     Message << "while building module '" << ModuleName << ":";
   emitNote(Loc, Message.str(), &SM);
 }
-
-
-void DiagnosticNoteRenderer::emitBasicNote(StringRef Message) {
-  emitNote(SourceLocation(), Message, nullptr);
-}
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index b085749..c274ba7 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -12,7 +12,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclGroup.h"
 #include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/ChainedIncludesSource.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
@@ -30,7 +29,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 using namespace clang;
 
 namespace {
@@ -260,7 +259,7 @@
     PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
     StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
     if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) {
-      llvm::error_code EC;
+      std::error_code EC;
       SmallString<128> DirNative;
       llvm::sys::path::native(PCHDir->getName(), DirNative);
       bool Found = false;
@@ -315,13 +314,12 @@
     
     if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
       // Convert headers to PCH and chain them.
-      IntrusiveRefCntPtr<ChainedIncludesSource> source;
-      source = ChainedIncludesSource::create(CI);
+      IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
+      source = createChainedIncludesSource(CI, FinalReader);
       if (!source)
         goto failure;
-      CI.setModuleManager(static_cast<ASTReader*>(&source->getFinalReader()));
+      CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get()));
       CI.getASTContext().setExternalSource(source);
-
     } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
       // Use PCH.
       assert(hasPCHSupport() && "This action does not have PCH support!");
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 5c56ee3..ef6bfec 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -24,8 +24,8 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include <memory>
+#include <system_error>
 
 using namespace clang;
 
@@ -129,10 +129,10 @@
   return Includes;
 }
 
-static llvm::error_code addHeaderInclude(StringRef HeaderName,
-                                         SmallVectorImpl<char> &Includes,
-                                         const LangOptions &LangOpts,
-                                         bool IsExternC) {
+static std::error_code addHeaderInclude(StringRef HeaderName,
+                                        SmallVectorImpl<char> &Includes,
+                                        const LangOptions &LangOpts,
+                                        bool IsExternC) {
   if (IsExternC && LangOpts.CPlusPlus)
     Includes += "extern \"C\" {\n";
   if (LangOpts.ObjC1)
@@ -146,20 +146,20 @@
     Includes += HeaderName;
   } else {
     SmallString<256> Header = HeaderName;
-    if (llvm::error_code Err = llvm::sys::fs::make_absolute(Header))
+    if (std::error_code Err = llvm::sys::fs::make_absolute(Header))
       return Err;
     Includes += Header;
   }
   Includes += "\"\n";
   if (IsExternC && LangOpts.CPlusPlus)
     Includes += "}\n";
-  return llvm::error_code::success();
+  return std::error_code();
 }
 
-static llvm::error_code addHeaderInclude(const FileEntry *Header,
-                                         SmallVectorImpl<char> &Includes,
-                                         const LangOptions &LangOpts,
-                                         bool IsExternC) {
+static std::error_code addHeaderInclude(const FileEntry *Header,
+                                        SmallVectorImpl<char> &Includes,
+                                        const LangOptions &LangOpts,
+                                        bool IsExternC) {
   return addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC);
 }
 
@@ -170,19 +170,19 @@
 ///
 /// \param Includes Will be augmented with the set of \#includes or \#imports
 /// needed to load all of the named headers.
-static llvm::error_code
+static std::error_code
 collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
                             ModuleMap &ModMap, clang::Module *Module,
                             SmallVectorImpl<char> &Includes) {
   // Don't collect any headers for unavailable modules.
   if (!Module->isAvailable())
-    return llvm::error_code::success();
+    return std::error_code();
 
   // Add includes for each of these headers.
   for (unsigned I = 0, N = Module->NormalHeaders.size(); I != N; ++I) {
     const FileEntry *Header = Module->NormalHeaders[I];
     Module->addTopHeader(Header);
-    if (llvm::error_code Err =
+    if (std::error_code Err =
             addHeaderInclude(Header, Includes, LangOpts, Module->IsExternC))
       return Err;
   }
@@ -192,13 +192,13 @@
     Module->addTopHeader(UmbrellaHeader);
     if (Module->Parent) {
       // Include the umbrella header for submodules.
-      if (llvm::error_code Err = addHeaderInclude(UmbrellaHeader, Includes,
-                                                  LangOpts, Module->IsExternC))
+      if (std::error_code Err = addHeaderInclude(UmbrellaHeader, Includes,
+                                                 LangOpts, Module->IsExternC))
         return Err;
     }
   } else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {
     // Add all of the headers we find in this subdirectory.
-    llvm::error_code EC;
+    std::error_code EC;
     SmallString<128> DirNative;
     llvm::sys::path::native(UmbrellaDir->getName(), DirNative);
     for (llvm::sys::fs::recursive_directory_iterator Dir(DirNative.str(), EC), 
@@ -220,8 +220,8 @@
       }
       
       // Include this header as part of the umbrella directory.
-      if (llvm::error_code Err = addHeaderInclude(Dir->path(), Includes,
-                                                  LangOpts, Module->IsExternC))
+      if (std::error_code Err = addHeaderInclude(Dir->path(), Includes,
+                                                 LangOpts, Module->IsExternC))
         return Err;
     }
 
@@ -233,11 +233,11 @@
   for (clang::Module::submodule_iterator Sub = Module->submodule_begin(),
                                       SubEnd = Module->submodule_end();
        Sub != SubEnd; ++Sub)
-    if (llvm::error_code Err = collectModuleHeaderIncludes(
+    if (std::error_code Err = collectModuleHeaderIncludes(
             LangOpts, FileMgr, ModMap, *Sub, Includes))
       return Err;
 
-  return llvm::error_code::success();
+  return std::error_code();
 }
 
 bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, 
@@ -310,7 +310,7 @@
 
   // Collect the set of #includes we need to build the module.
   SmallString<256> HeaderContents;
-  llvm::error_code Err = llvm::error_code::success();
+  std::error_code Err = std::error_code();
   if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader())
     Err = addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts(),
                            Module->IsExternC);
diff --git a/lib/Frontend/HeaderIncludeGen.cpp b/lib/Frontend/HeaderIncludeGen.cpp
index 6d2e378..8b2435b 100644
--- a/lib/Frontend/HeaderIncludeGen.cpp
+++ b/lib/Frontend/HeaderIncludeGen.cpp
@@ -49,7 +49,7 @@
 void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders,
                                    StringRef OutputPath, bool ShowDepth,
                                    bool MSStyle) {
-  raw_ostream *OutputFile = &llvm::errs();
+  raw_ostream *OutputFile = MSStyle ? &llvm::outs() : &llvm::errs();
   bool OwnsOutputFile = false;
 
   // Open the output file, if used.
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index d2890f0..d2edc94 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -472,7 +472,8 @@
 
   case llvm::Triple::Win32:
     if (triple.getEnvironment() == llvm::Triple::MSVC ||
-        triple.getEnvironment() == llvm::Triple::Itanium)
+        triple.getEnvironment() == llvm::Triple::Itanium ||
+        triple.getObjectFormat() == llvm::Triple::MachO)
       return;
     break;
   }
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index fb52eb4..f03348d 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -180,7 +180,7 @@
 /// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro
 /// named MacroName with the max value for a type with width 'TypeWidth' a
 /// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL).
-static void DefineTypeSize(StringRef MacroName, unsigned TypeWidth,
+static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth,
                            StringRef ValSuffix, bool isSigned,
                            MacroBuilder &Builder) {
   llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth)
@@ -190,7 +190,7 @@
 
 /// DefineTypeSize - An overloaded helper that uses TargetInfo to determine
 /// the width, suffix, and signedness of the given type
-static void DefineTypeSize(StringRef MacroName, TargetInfo::IntType Ty,
+static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty,
                            const TargetInfo &TI, MacroBuilder &Builder) {
   DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), 
                  TI.isTypeSigned(Ty), Builder);
@@ -212,23 +212,68 @@
                       Twine(BitWidth / TI.getCharWidth()));
 }
 
-static void DefineExactWidthIntType(TargetInfo::IntType Ty, 
-                               const TargetInfo &TI, MacroBuilder &Builder) {
+static void DefineExactWidthIntType(TargetInfo::IntType Ty,
+                                    const TargetInfo &TI,
+                                    MacroBuilder &Builder) {
   int TypeWidth = TI.getTypeWidth(Ty);
+  bool IsSigned = TI.isTypeSigned(Ty);
 
   // Use the target specified int64 type, when appropriate, so that [u]int64_t
   // ends up being defined in terms of the correct type.
   if (TypeWidth == 64)
-    Ty = TI.getInt64Type();
+    Ty = IsSigned ? TI.getInt64Type() : TI.getIntTypeByWidth(64, false);
 
-  DefineType("__INT" + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+  const char *Prefix = IsSigned ? "__INT" : "__UINT";
+
+  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
 
   StringRef ConstSuffix(TargetInfo::getTypeConstantSuffix(Ty));
   if (!ConstSuffix.empty())
-    Builder.defineMacro("__INT" + Twine(TypeWidth) + "_C_SUFFIX__",
-                        ConstSuffix);
+    Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
+
 }
 
+static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty,
+                                        const TargetInfo &TI,
+                                        MacroBuilder &Builder) {
+  int TypeWidth = TI.getTypeWidth(Ty);
+  bool IsSigned = TI.isTypeSigned(Ty);
+
+  // Use the target specified int64 type, when appropriate, so that [u]int64_t
+  // ends up being defined in terms of the correct type.
+  if (TypeWidth == 64)
+    Ty = IsSigned ? TI.getInt64Type() : TI.getIntTypeByWidth(64, false);
+
+  const char *Prefix = IsSigned ? "__INT" : "__UINT";
+  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+}
+
+static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned,
+                                    const TargetInfo &TI,
+                                    MacroBuilder &Builder) {
+  TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
+  if (Ty == TargetInfo::NoInt)
+    return;
+
+  const char *Prefix = IsSigned ? "__INT_LEAST" : "__UINT_LEAST";
+  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+}
+
+static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
+                              const TargetInfo &TI, MacroBuilder &Builder) {
+  // stdint.h currently defines the fast int types as equivalent to the least
+  // types.
+  TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
+  if (Ty == TargetInfo::NoInt)
+    return;
+
+  const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST";
+  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+}
+
+
 /// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with
 /// the specified properties.
 static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign,
@@ -315,10 +360,13 @@
     else if (!LangOpts.GNUMode && LangOpts.Digraphs)
       Builder.defineMacro("__STDC_VERSION__", "199409L");
   } else {
+    // FIXME: Use correct value for C++17.
+    if (LangOpts.CPlusPlus1z)
+      Builder.defineMacro("__cplusplus", "201406L");
     // C++1y [cpp.predefined]p1:
     //   The name __cplusplus is defined to the value 201402L when compiling a
     //   C++ translation unit.
-     if (LangOpts.CPlusPlus1y)
+    else if (LangOpts.CPlusPlus1y)
       Builder.defineMacro("__cplusplus", "201402L");
     // C++11 [cpp.predefined]p1:
     //   The name __cplusplus is defined to the value 201103L when compiling a
@@ -430,7 +478,7 @@
   // Initialize language-specific preprocessor defines.
 
   // Standard conforming mode?
-  if (!LangOpts.GNUMode)
+  if (!LangOpts.GNUMode && !LangOpts.MSVCCompat)
     Builder.defineMacro("__STRICT_ANSI__");
 
   if (LangOpts.CPlusPlus11)
@@ -491,7 +539,7 @@
     Builder.defineMacro("__BLOCKS__");
   }
 
-  if (LangOpts.CXXExceptions)
+  if (!LangOpts.MSVCCompat && LangOpts.CXXExceptions)
     Builder.defineMacro("__EXCEPTIONS");
   if (LangOpts.RTTI)
     Builder.defineMacro("__GXX_RTTI");
@@ -560,6 +608,13 @@
   DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder);
   DefineTypeSize("__SIZE_MAX__", TI.getSizeType(), TI, Builder);
 
+  if (!LangOpts.MSVCCompat) {
+    DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder);
+    DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder);
+    DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder);
+    DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder);
+  }
+
   DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder);
   DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder);
   DefineTypeSizeof("__SIZEOF_INT__", TI.getIntWidth(), TI, Builder);
@@ -596,6 +651,12 @@
   DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
   DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);
 
+  if (!LangOpts.MSVCCompat) {
+    DefineTypeWidth("__UINTMAX_WIDTH__",  TI.getUIntMaxType(), TI, Builder);
+    DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
+    DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder);
+  }
+
   DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F");
   DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), "");
   DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat(), "L");
@@ -629,6 +690,54 @@
   if (TI.getLongLongWidth() > TI.getLongWidth())
     DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder);
 
+  if (!LangOpts.MSVCCompat) {
+    DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder);
+
+    if (TI.getShortWidth() > TI.getCharWidth()) {
+      DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder);
+    }
+
+    if (TI.getIntWidth() > TI.getShortWidth()) {
+      DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder);
+    }
+
+    if (TI.getLongWidth() > TI.getIntWidth()) {
+      DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder);
+    }
+
+    if (TI.getLongLongWidth() > TI.getLongWidth()) {
+      DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder);
+    }
+
+    DefineLeastWidthIntType(8, true, TI, Builder);
+    DefineLeastWidthIntType(8, false, TI, Builder);
+    DefineLeastWidthIntType(16, true, TI, Builder);
+    DefineLeastWidthIntType(16, false, TI, Builder);
+    DefineLeastWidthIntType(32, true, TI, Builder);
+    DefineLeastWidthIntType(32, false, TI, Builder);
+    DefineLeastWidthIntType(64, true, TI, Builder);
+    DefineLeastWidthIntType(64, false, TI, Builder);
+
+    DefineFastIntType(8, true, TI, Builder);
+    DefineFastIntType(8, false, TI, Builder);
+    DefineFastIntType(16, true, TI, Builder);
+    DefineFastIntType(16, false, TI, Builder);
+    DefineFastIntType(32, true, TI, Builder);
+    DefineFastIntType(32, false, TI, Builder);
+    DefineFastIntType(64, true, TI, Builder);
+    DefineFastIntType(64, false, TI, Builder);
+  }
+
   if (const char *Prefix = TI.getUserLabelPrefix())
     Builder.defineMacro("__USER_LABEL_PREFIX__", Prefix);
 
@@ -726,74 +835,11 @@
   TI.getTargetDefines(LangOpts, Builder);
 }
 
-// Initialize the remapping of files to alternative contents, e.g.,
-// those specified through other files.
-static void InitializeFileRemapping(DiagnosticsEngine &Diags,
-                                    SourceManager &SourceMgr,
-                                    FileManager &FileMgr,
-                                    const PreprocessorOptions &InitOpts) {
-  // Remap files in the source manager (with buffers).
-  for (PreprocessorOptions::const_remapped_file_buffer_iterator
-         Remap = InitOpts.remapped_file_buffer_begin(),
-         RemapEnd = InitOpts.remapped_file_buffer_end();
-       Remap != RemapEnd;
-       ++Remap) {
-    // Create the file entry for the file that we're mapping from.
-    const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
-                                                Remap->second->getBufferSize(),
-                                                       0);
-    if (!FromFile) {
-      Diags.Report(diag::err_fe_remap_missing_from_file)
-        << Remap->first;
-      if (!InitOpts.RetainRemappedFileBuffers)
-        delete Remap->second;
-      continue;
-    }
-
-    // Override the contents of the "from" file with the contents of
-    // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, Remap->second,
-                                   InitOpts.RetainRemappedFileBuffers);
-  }
-
-  // Remap files in the source manager (with other files).
-  for (PreprocessorOptions::const_remapped_file_iterator
-         Remap = InitOpts.remapped_file_begin(),
-         RemapEnd = InitOpts.remapped_file_end();
-       Remap != RemapEnd;
-       ++Remap) {
-    // Find the file that we're mapping to.
-    const FileEntry *ToFile = FileMgr.getFile(Remap->second);
-    if (!ToFile) {
-      Diags.Report(diag::err_fe_remap_missing_to_file)
-      << Remap->first << Remap->second;
-      continue;
-    }
-    
-    // Create the file entry for the file that we're mapping from.
-    const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
-                                                       ToFile->getSize(), 0);
-    if (!FromFile) {
-      Diags.Report(diag::err_fe_remap_missing_from_file)
-      << Remap->first;
-      continue;
-    }
-    
-    // Override the contents of the "from" file with the contents of
-    // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, ToFile);
-  }
-
-  SourceMgr.setOverridenFilesKeepOriginalName(
-                                        InitOpts.RemappedFilesKeepOriginalName);
-}
-
 /// InitializePreprocessor - Initialize the preprocessor getting it and the
 /// environment ready to process a single file. This returns true on error.
 ///
 void clang::InitializePreprocessor(Preprocessor &PP,
                                    const PreprocessorOptions &InitOpts,
-                                   const HeaderSearchOptions &HSOpts,
                                    const FrontendOptions &FEOpts) {
   const LangOptions &LangOpts = PP.getLangOpts();
   std::string PredefineBuffer;
@@ -801,9 +847,6 @@
   llvm::raw_string_ostream Predefines(PredefineBuffer);
   MacroBuilder Builder(Predefines);
 
-  InitializeFileRemapping(PP.getDiagnostics(), PP.getSourceManager(),
-                          PP.getFileManager(), InitOpts);
-
   // Emit line markers for various builtin sections of the file.  We don't do
   // this in asm preprocessor mode, because "# 4" is not a line marker directive
   // in this mode.
@@ -877,9 +920,4 @@
                           
   // Copy PredefinedBuffer into the Preprocessor.
   PP.setPredefines(Predefines.str());
-  
-  // Initialize the header search object.
-  ApplyHeaderSearchOptions(PP.getHeaderSearchInfo(), HSOpts,
-                           PP.getLangOpts(),
-                           PP.getTargetInfo().getTriple());
 }
diff --git a/lib/Frontend/LogDiagnosticPrinter.cpp b/lib/Frontend/LogDiagnosticPrinter.cpp
index 917c13f..19539e0 100644
--- a/lib/Frontend/LogDiagnosticPrinter.cpp
+++ b/lib/Frontend/LogDiagnosticPrinter.cpp
@@ -10,11 +10,13 @@
 #include "clang/Frontend/LogDiagnosticPrinter.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/PlistSupport.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
+using namespace markup;
 
 LogDiagnosticPrinter::LogDiagnosticPrinter(raw_ostream &os,
                                            DiagnosticOptions *diags,
@@ -40,19 +42,34 @@
   llvm_unreachable("Invalid DiagnosticsEngine level!");
 }
 
-// Escape XML characters inside the raw string.
-static void emitString(llvm::raw_svector_ostream &OS, const StringRef Raw) {
-  for (StringRef::iterator I = Raw.begin(), E = Raw.end(); I != E; ++I) {
-    char c = *I;
-    switch (c) {
-    default:   OS << c; break;
-    case '&':  OS << "&amp;"; break;
-    case '<':  OS << "&lt;"; break;
-    case '>':  OS << "&gt;"; break;
-    case '\'': OS << "&apos;"; break;
-    case '\"': OS << "&quot;"; break;
-    }
+void
+LogDiagnosticPrinter::EmitDiagEntry(llvm::raw_ostream &OS,
+                                    const LogDiagnosticPrinter::DiagEntry &DE) {
+  OS << "    <dict>\n";
+  OS << "      <key>level</key>\n"
+     << "      ";
+  EmitString(OS, getLevelName(DE.DiagnosticLevel)) << '\n';
+  if (!DE.Filename.empty()) {
+    OS << "      <key>filename</key>\n"
+       << "      ";
+    EmitString(OS, DE.Filename) << '\n';
   }
+  if (DE.Line != 0) {
+    OS << "      <key>line</key>\n"
+       << "      ";
+    EmitInteger(OS, DE.Line) << '\n';
+  }
+  if (DE.Column != 0) {
+    OS << "      <key>column</key>\n"
+       << "      ";
+    EmitInteger(OS, DE.Column) << '\n';
+  }
+  if (!DE.Message.empty()) {
+    OS << "      <key>message</key>\n"
+       << "      ";
+    EmitString(OS, DE.Message) << '\n';
+  }
+  OS << "    </dict>\n";
 }
 
 void LogDiagnosticPrinter::EndSourceFile() {
@@ -72,48 +89,18 @@
   OS << "<dict>\n";
   if (!MainFilename.empty()) {
     OS << "  <key>main-file</key>\n"
-       << "  <string>";
-    emitString(OS, MainFilename);
-    OS << "</string>\n";
+       << "  ";
+    EmitString(OS, MainFilename) << '\n';
   }
   if (!DwarfDebugFlags.empty()) {
     OS << "  <key>dwarf-debug-flags</key>\n"
-       << "  <string>";
-    emitString(OS, DwarfDebugFlags);
-    OS << "</string>\n";
+       << "  ";
+    EmitString(OS, DwarfDebugFlags) << '\n';
   }
   OS << "  <key>diagnostics</key>\n";
   OS << "  <array>\n";
-  for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
-    DiagEntry &DE = Entries[i];
-
-    OS << "    <dict>\n";
-    OS << "      <key>level</key>\n"
-       << "      <string>";
-    emitString(OS, getLevelName(DE.DiagnosticLevel));
-    OS << "</string>\n";
-    if (!DE.Filename.empty()) {
-      OS << "      <key>filename</key>\n"
-         << "      <string>";
-      emitString(OS, DE.Filename);
-      OS << "</string>\n";
-    }
-    if (DE.Line != 0) {
-      OS << "      <key>line</key>\n"
-         << "      <integer>" << DE.Line << "</integer>\n";
-    }
-    if (DE.Column != 0) {
-      OS << "      <key>column</key>\n"
-         << "      <integer>" << DE.Column << "</integer>\n";
-    }
-    if (!DE.Message.empty()) {
-      OS << "      <key>message</key>\n"
-         << "      <string>";
-      emitString(OS, DE.Message);
-      OS << "</string>\n";
-    }
-    OS << "    </dict>\n";
-  }
+  for (auto &DE : Entries)
+    EmitDiagEntry(OS, DE);
   OS << "  </array>\n";
   OS << "</dict>\n";
 
diff --git a/lib/Frontend/ModuleDependencyCollector.cpp b/lib/Frontend/ModuleDependencyCollector.cpp
new file mode 100644
index 0000000..d30f921
--- /dev/null
+++ b/lib/Frontend/ModuleDependencyCollector.cpp
@@ -0,0 +1,116 @@
+//===--- ModuleDependencyCollector.cpp - Collect module dependencies ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect the dependencies of a set of modules.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Serialization/ASTReader.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+namespace {
+/// Private implementation for ModuleDependencyCollector
+class ModuleDependencyListener : public ASTReaderListener {
+  ModuleDependencyCollector &Collector;
+
+  std::error_code copyToRoot(StringRef Src);
+public:
+  ModuleDependencyListener(ModuleDependencyCollector &Collector)
+      : Collector(Collector) {}
+  bool needsInputFileVisitation() override { return true; }
+  bool needsSystemInputFileVisitation() override { return true; }
+  bool visitInputFile(StringRef Filename, bool IsSystem,
+                      bool IsOverridden) override;
+};
+}
+
+void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
+  R.addListener(new ModuleDependencyListener(*this));
+}
+
+void ModuleDependencyCollector::writeFileMap() {
+  if (Seen.empty())
+    return;
+
+  SmallString<256> Dest = getDest();
+  llvm::sys::path::append(Dest, "vfs.yaml");
+
+  std::string ErrorInfo;
+  llvm::raw_fd_ostream OS(Dest.c_str(), ErrorInfo, llvm::sys::fs::F_Text);
+  if (!ErrorInfo.empty()) {
+    setHasErrors();
+    return;
+  }
+  VFSWriter.write(OS);
+}
+
+/// Remove traversal (ie, . or ..) from the given absolute path.
+static void removePathTraversal(SmallVectorImpl<char> &Path) {
+  using namespace llvm::sys;
+  SmallVector<StringRef, 16> ComponentStack;
+  StringRef P(Path.data(), Path.size());
+
+  // Skip the root path, then look for traversal in the components.
+  StringRef Rel = path::relative_path(P);
+  for (StringRef C : llvm::make_range(path::begin(Rel), path::end(Rel))) {
+    if (C == ".")
+      continue;
+    if (C == "..") {
+      assert(ComponentStack.size() && "Path traverses out of parent");
+      ComponentStack.pop_back();
+    } else
+      ComponentStack.push_back(C);
+  }
+
+  // The stack is now the path without any directory traversal.
+  SmallString<256> Buffer = path::root_path(P);
+  for (StringRef C : ComponentStack)
+    path::append(Buffer, C);
+
+  // Put the result in Path.
+  Path.swap(Buffer);
+}
+
+std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) {
+  using namespace llvm::sys;
+
+  // We need an absolute path to append to the root.
+  SmallString<256> AbsoluteSrc = Src;
+  fs::make_absolute(AbsoluteSrc);
+  removePathTraversal(AbsoluteSrc);
+
+  // Build the destination path.
+  SmallString<256> Dest = Collector.getDest();
+  path::append(Dest, path::relative_path(AbsoluteSrc));
+
+  // Copy the file into place.
+  if (std::error_code EC = fs::create_directories(path::parent_path(Dest),
+                                                   /*IgnoreExisting=*/true))
+    return EC;
+  if (std::error_code EC = fs::copy_file(AbsoluteSrc.str(), Dest.str()))
+    return EC;
+  // Use the absolute path under the root for the file mapping.
+  Collector.addFileMapping(AbsoluteSrc.str(), Dest.str());
+  return std::error_code();
+}
+
+bool ModuleDependencyListener::visitInputFile(StringRef Filename, bool IsSystem,
+                                              bool IsOverridden) {
+  if (Collector.insertSeen(Filename))
+    if (copyToRoot(Filename))
+      Collector.setHasErrors();
+  return true;
+}
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 8c32c24..4a6f8db 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -139,7 +139,7 @@
   void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override;
   void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override;
   void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
-                        diag::Mapping Map, StringRef Str) override;
+                        diag::Severity Map, StringRef Str) override;
   void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
                      ArrayRef<int> Ids) override;
   void PragmaWarningPush(SourceLocation Loc, int Level) override;
@@ -439,26 +439,27 @@
   setEmittedDirectiveOnThisLine();
 }
 
-void PrintPPOutputPPCallbacks::
-PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
-                 diag::Mapping Map, StringRef Str) {
+void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
+                                                StringRef Namespace,
+                                                diag::Severity Map,
+                                                StringRef Str) {
   startNewLineIfNeeded();
   MoveToLine(Loc);
   OS << "#pragma " << Namespace << " diagnostic ";
   switch (Map) {
-  case diag::MAP_REMARK:
+  case diag::Severity::Remark:
     OS << "remark";
     break;
-  case diag::MAP_WARNING:
+  case diag::Severity::Warning:
     OS << "warning";
     break;
-  case diag::MAP_ERROR:
+  case diag::Severity::Error:
     OS << "error";
     break;
-  case diag::MAP_IGNORE:
+  case diag::Severity::Ignored:
     OS << "ignored";
     break;
-  case diag::MAP_FATAL:
+  case diag::Severity::Fatal:
     OS << "fatal";
     break;
   }
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index 4c90d01..dc67d68 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -689,8 +689,9 @@
   
   printDiagnosticLevel(OS, Level, DiagOpts->ShowColors,
                        DiagOpts->CLFallbackMode);
-  printDiagnosticMessage(OS, Level, Message,
-                         OS.tell() - StartOfLocationInfo,
+  printDiagnosticMessage(OS,
+                         /*IsSupplemental*/ Level == DiagnosticsEngine::Note,
+                         Message, OS.tell() - StartOfLocationInfo,
                          DiagOpts->MessageLength, DiagOpts->ShowColors);
 }
 
@@ -735,24 +736,18 @@
     OS.resetColor();
 }
 
-/*static*/ void
-TextDiagnostic::printDiagnosticMessage(raw_ostream &OS,
-                                       DiagnosticsEngine::Level Level,
-                                       StringRef Message,
-                                       unsigned CurrentColumn, unsigned Columns,
-                                       bool ShowColors) {
+/*static*/
+void TextDiagnostic::printDiagnosticMessage(raw_ostream &OS,
+                                            bool IsSupplemental,
+                                            StringRef Message,
+                                            unsigned CurrentColumn,
+                                            unsigned Columns, bool ShowColors) {
   bool Bold = false;
-  if (ShowColors) {
-    // Print warnings, errors and fatal errors in bold, no color
-    switch (Level) {
-    case DiagnosticsEngine::Warning:
-    case DiagnosticsEngine::Error:
-    case DiagnosticsEngine::Fatal:
-      OS.changeColor(savedColor, true);
-      Bold = true;
-      break;
-    default: break; //don't bold notes
-    }
+  if (ShowColors && !IsSupplemental) {
+    // Print primary diagnostic messages in bold and without color, to visually
+    // indicate the transition from continuation notes and other output.
+    OS.changeColor(savedColor, true);
+    Bold = true;
   }
 
   if (Columns)
@@ -813,7 +808,7 @@
       if (DiagOpts->getFormat() == DiagnosticOptions::Msvc) {
         OS << ',';
         // Visual Studio 2010 or earlier expects column number to be off by one
-        if (LangOpts.MSCVersion && LangOpts.MSCVersion < 1700)
+        if (LangOpts.MSCVersion && LangOpts.MSCVersion < 170000000)
           ColNo--;
       } else
         OS << ':';
@@ -875,12 +870,6 @@
   OS << ' ';
 }
 
-void TextDiagnostic::emitBasicNote(StringRef Message) {
-  // FIXME: Emit this as a real note diagnostic.
-  // FIXME: Format an actual diagnostic rather than a hard coded string.
-  OS << "note: " << Message << "\n";
-}
-
 void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
                                          PresumedLoc PLoc,
                                          const SourceManager &SM) {
@@ -1141,7 +1130,7 @@
   std::string FixItInsertionLine = buildFixItInsertionLine(LineNo,
                                                            sourceColMap,
                                                            Hints, SM,
-                                                           DiagOpts.getPtr());
+                                                           DiagOpts.get());
 
   // If the source line is too long for our terminal, select only the
   // "interesting" source region within that line.
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index d6df655..6271509 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -82,8 +82,8 @@
     StringRef Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID());
     if (!Opt.empty()) {
       OS << (Started ? "," : " [")
-         << (DiagnosticIDs::isRemark(Info.getID()) ? "-R" : "-W") << Opt;
-      StringRef OptValue = Info.getDiags()->getFlagNameValue();
+         << (Level == DiagnosticsEngine::Remark ? "-R" : "-W") << Opt;
+      StringRef OptValue = Info.getDiags()->getFlagValue();
       if (!OptValue.empty())
         OS << "=" << OptValue;
       Started = true;
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index 856b51d..b50950e 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -164,8 +164,9 @@
 class StandardDirective : public Directive {
 public:
   StandardDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-                    StringRef Text, unsigned Min, unsigned Max)
-    : Directive(DirectiveLoc, DiagnosticLoc, Text, Min, Max) { }
+                    bool MatchAnyLine, StringRef Text, unsigned Min,
+                    unsigned Max)
+    : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max) { }
 
   bool isValid(std::string &Error) override {
     // all strings are considered valid; even empty ones
@@ -182,8 +183,10 @@
 class RegexDirective : public Directive {
 public:
   RegexDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-                 StringRef Text, unsigned Min, unsigned Max, StringRef RegexStr)
-    : Directive(DirectiveLoc, DiagnosticLoc, Text, Min, Max), Regex(RegexStr) { }
+                 bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max,
+                 StringRef RegexStr)
+    : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max),
+      Regex(RegexStr) { }
 
   bool isValid(std::string &Error) override {
     if (Regex.isValid(Error))
@@ -371,6 +374,7 @@
 
     // Next optional token: @
     SourceLocation ExpectedLoc;
+    bool MatchAnyLine = false;
     if (!PH.Next("@")) {
       ExpectedLoc = Pos;
     } else {
@@ -411,6 +415,10 @@
 
         if (PH.Next(Line) && Line > 0)
           ExpectedLoc = SM.translateFileLineCol(FE, Line, 1);
+        else if (PH.Next("*")) {
+          MatchAnyLine = true;
+          ExpectedLoc = SM.translateFileLineCol(FE, 1, 1);
+        }
       }
 
       if (ExpectedLoc.isInvalid()) {
@@ -495,7 +503,8 @@
 
     // Construct new directive.
     std::unique_ptr<Directive> D(
-        Directive::create(RegexKind, Pos, ExpectedLoc, Text, Min, Max));
+        Directive::create(RegexKind, Pos, ExpectedLoc, MatchAnyLine, Text,
+                          Min, Max));
 
     std::string Error;
     if (D->isValid(Error)) {
@@ -644,8 +653,11 @@
   llvm::raw_svector_ostream OS(Fmt);
   for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) {
     Directive &D = **I;
-    OS << "\n  File " << SourceMgr.getFilename(D.DiagnosticLoc)
-          << " Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
+    OS << "\n  File " << SourceMgr.getFilename(D.DiagnosticLoc);
+    if (D.MatchAnyLine)
+      OS << " Line *";
+    else
+      OS << " Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
     if (D.DirectiveLoc != D.DiagnosticLoc)
       OS << " (directive at "
          << SourceMgr.getFilename(D.DirectiveLoc) << ':'
@@ -692,9 +704,11 @@
     for (unsigned i = 0; i < D.Max; ++i) {
       DiagList::iterator II, IE;
       for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
-        unsigned LineNo2 = SourceMgr.getPresumedLineNumber(II->first);
-        if (LineNo1 != LineNo2)
-          continue;
+        if (!D.MatchAnyLine) {
+          unsigned LineNo2 = SourceMgr.getPresumedLineNumber(II->first);
+          if (LineNo1 != LineNo2)
+            continue;
+        }
 
         if (!IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first))
           continue;
@@ -859,10 +873,11 @@
 }
 
 Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc,
-                             SourceLocation DiagnosticLoc, StringRef Text,
-                             unsigned Min, unsigned Max) {
+                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
+                             StringRef Text, unsigned Min, unsigned Max) {
   if (!RegexKind)
-    return new StandardDirective(DirectiveLoc, DiagnosticLoc, Text, Min, Max);
+    return new StandardDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine,
+                                 Text, Min, Max);
 
   // Parse the directive into a regular expression.
   std::string RegexStr;
@@ -887,6 +902,6 @@
     }
   }
 
-  return new RegexDirective(DirectiveLoc, DiagnosticLoc, Text, Min, Max,
-                            RegexStr);
+  return new RegexDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text,
+                            Min, Max, RegexStr);
 }
diff --git a/lib/Headers/Android.mk b/lib/Headers/Android.mk
index 117129e..c1df621 100644
--- a/lib/Headers/Android.mk
+++ b/lib/Headers/Android.mk
@@ -4,7 +4,7 @@
 
 $(TARGET_OUT_HEADERS)/clang/arm_neon.h: TBLGEN_LOCAL_MODULE := arm_neon.h
 $(TARGET_OUT_HEADERS)/clang/arm_neon.h: $(CLANG_ROOT_PATH)/include/clang/Basic/arm_neon.td \
-    | $(CLANG_TBLGEN)
+    $(CLANG_TBLGEN)
 	$(call transform-host-clang-td-to-out,arm-neon)
 
 # Make sure when clang is used, arm_neon.h does exist.
diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt
index 23b2446..edee7d7 100644
--- a/lib/Headers/CMakeLists.txt
+++ b/lib/Headers/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(files
   altivec.h
   ammintrin.h
+  arm_acle.h
   avxintrin.h
   avx2intrin.h
   bmiintrin.h
diff --git a/lib/Headers/Intrin.h b/lib/Headers/Intrin.h
index ff6d278..13e105e 100644
--- a/lib/Headers/Intrin.h
+++ b/lib/Headers/Intrin.h
@@ -30,21 +30,27 @@
 #define __INTRIN_H
 
 /* First include the standard intrinsics. */
+#if defined(__i386__) || defined(__x86_64__)
 #include <x86intrin.h>
+#endif
 
 /* For the definition of jmp_buf. */
+#if __STDC_HOSTED__
 #include <setjmp.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if defined(__MMX__)
 /* And the random ones that aren't in those files. */
 __m64 _m_from_float(float);
 __m64 _m_from_int(int _l);
 void _m_prefetch(void *);
 float _m_to_float(__m64);
 int _m_to_int(__m64 _M);
+#endif
 
 /* Other assorted instruction intrinsics. */
 void __addfsbyte(unsigned long, unsigned char);
@@ -223,8 +229,7 @@
 long __cdecl _InterlockedDecrement(long volatile *_Addend);
 static __inline__
 short _InterlockedDecrement16(short volatile *_Addend);
-static __inline__
-long __cdecl _InterlockedExchange(long volatile *_Target, long _Value);
+long _InterlockedExchange(long volatile *_Target, long _Value);
 static __inline__
 short _InterlockedExchange16(short volatile *_Target, short _Value);
 static __inline__
@@ -288,7 +293,9 @@
 static __inline__
 unsigned char _rotr8(unsigned char _Value, unsigned char _Shift);
 int _sarx_i32(int, unsigned int);
+#if __STDC_HOSTED__
 int __cdecl _setjmp(jmp_buf);
+#endif
 unsigned int _shlx_u32(unsigned int, unsigned int);
 unsigned int _shrx_u32(unsigned int, unsigned int);
 void _Store_HLERelease(long volatile *, long);
@@ -411,7 +418,6 @@
                                                  __int64);
 __int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination,
                                          __int64 _Exchange, __int64 _Comparand);
-static __inline__
 void *_InterlockedCompareExchangePointer(void *volatile *_Destination,
                                          void *_Exchange, void *_Comparand);
 void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination,
@@ -422,7 +428,6 @@
 __int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value);
 static __inline__
 __int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value);
-static __inline__
 void *_InterlockedExchangePointer(void *volatile *_Target, void *_Value);
 static __inline__
 __int64 _InterlockedIncrement64(__int64 volatile *_Addend);
@@ -448,8 +453,9 @@
 unsigned __int64 __cdecl _readgsbase_u64(void);
 unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int);
 __int64 _sarx_i64(__int64, unsigned int);
-/* FIXME: Need definition for jmp_buf.
-  int __cdecl _setjmpex(jmp_buf); */
+#if __STDC_HOSTED__
+int __cdecl _setjmpex(jmp_buf);
+#endif
 unsigned __int64 _shlx_u64(unsigned __int64, unsigned int);
 unsigned __int64 shrx_u64(unsigned __int64, unsigned int);
 unsigned __int64 _tzcnt_u64(unsigned __int64);
@@ -575,6 +581,7 @@
   *a = *a | (1 << b);
   return x;
 }
+#if defined(__i386__) || defined(__x86_64__)
 static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
 _interlockedbittestandset(long volatile *__BitBase, long __BitPos) {
   unsigned char __Res;
@@ -585,6 +592,7 @@
            : "Ir"(__BitPos));
   return __Res;
 }
+#endif
 #ifdef __x86_64__
 static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
 _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) {
@@ -785,22 +793,12 @@
   __atomic_exchange(_Target, &_Value, &_Value, 0);
   return _Value;
 }
-static __inline__ long __attribute__((__always_inline__, __nodebug__))
-_InterlockedExchange(long volatile *_Target, long _Value) {
-  __atomic_exchange(_Target, &_Value, &_Value, 0);
-  return _Value;
-}
 #ifdef __x86_64__
 static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value) {
   __atomic_exchange(_Target, &_Value, &_Value, 0);
   return _Value;
 }
-static __inline__ void *__attribute__((__always_inline__, __nodebug__))
-_InterlockedExchangePointer(void *volatile *_Target, void *_Value) {
-  __atomic_exchange(_Target, &_Value, &_Value, 0);
-  return _Value;
-}
 #endif
 /*----------------------------------------------------------------------------*\
 |* Interlocked Compare Exchange
@@ -817,14 +815,6 @@
   __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);
   return _Comparand;
 }
-#ifdef __x86_64__
-static __inline__ void *__attribute__((__always_inline__, __nodebug__))
-_InterlockedCompareExchangePointer(void *volatile *_Destination,
-                                   void *_Exchange, void *_Comparand) {
-  __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);
-  return _Comparand;
-}
-#endif
 static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
 _InterlockedCompareExchange64(__int64 volatile *_Destination,
                               __int64 _Exchange, __int64 _Comparand) {
@@ -834,6 +824,7 @@
 /*----------------------------------------------------------------------------*\
 |* Barriers
 \*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 __attribute__((deprecated("use other intrinsics or C++11 atomics instead")))
 _ReadWriteBarrier(void) {
@@ -849,6 +840,7 @@
 _WriteBarrier(void) {
   __asm__ volatile ("" : : : "memory");
 }
+#endif
 #ifdef __x86_64__
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 __faststorefence(void) {
@@ -904,6 +896,7 @@
 /*----------------------------------------------------------------------------*\
 |* movs, stos
 \*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 __movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) {
   __asm__("rep movsb" : : "D"(__dst), "S"(__src), "c"(__n)
@@ -934,6 +927,7 @@
   __asm__("rep stosh" : : "D"(__dst), "a"(__x), "c"(__n)
                         : "%edi", "%ecx");
 }
+#endif
 #ifdef __x86_64__
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 __movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
@@ -958,6 +952,7 @@
 _ReturnAddress(void) {
   return __builtin_return_address(0);
 }
+#if defined(__i386__) || defined(__x86_64__)
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 __cpuid(int __info[4], int __level) {
   __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3])
@@ -978,10 +973,12 @@
 __halt(void) {
   __asm__ volatile ("hlt");
 }
+#endif
 
 /*----------------------------------------------------------------------------*\
 |* Privileged intrinsics
 \*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
 static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
 __readmsr(unsigned long __register) {
   // Loads the contents of a 64-bit model specific register (MSR) specified in
@@ -1007,6 +1004,7 @@
 __writecr3(unsigned int __cr3_val) {
   __asm__ ("mov %0, %%cr3" : : "q"(__cr3_val) : "memory");
 }
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h
index 74ce08a..7a4a774 100644
--- a/lib/Headers/altivec.h
+++ b/lib/Headers/altivec.h
@@ -73,6 +73,9 @@
 static vector float __ATTRS_o_ai
 vec_perm(vector float __a, vector float __b, vector unsigned char __c);
 
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector unsigned char __a, vector unsigned char __b);
+
 /* vec_abs */
 
 #define __builtin_altivec_abs_v16qi vec_abs
@@ -3485,30 +3488,49 @@
   __builtin_altivec_mtvscr((vector int)__a);
 }
 
+/* The vmulos* and vmules* instructions have a big endian bias, so
+   we must reverse the meaning of "even" and "odd" for little endian.  */
+
 /* vec_mule */
 
 static vector short __ATTRS_o_ai
 vec_mule(vector signed char __a, vector signed char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosb(__a, __b);
+#else
   return __builtin_altivec_vmulesb(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_mule(vector unsigned char __a, vector unsigned char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuloub(__a, __b);
+#else
   return __builtin_altivec_vmuleub(__a, __b);
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_mule(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosh(__a, __b);
+#else
   return __builtin_altivec_vmulesh(__a, __b);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_mule(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulouh(__a, __b);
+#else
   return __builtin_altivec_vmuleuh(__a, __b);
+#endif
 }
 
 /* vec_vmulesb */
@@ -3516,7 +3538,11 @@
 static vector short __attribute__((__always_inline__))
 vec_vmulesb(vector signed char __a, vector signed char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosb(__a, __b);
+#else
   return __builtin_altivec_vmulesb(__a, __b);
+#endif
 }
 
 /* vec_vmuleub */
@@ -3524,7 +3550,11 @@
 static vector unsigned short __attribute__((__always_inline__))
 vec_vmuleub(vector unsigned char __a, vector unsigned char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuloub(__a, __b);
+#else
   return __builtin_altivec_vmuleub(__a, __b);
+#endif
 }
 
 /* vec_vmulesh */
@@ -3532,7 +3562,11 @@
 static vector int __attribute__((__always_inline__))
 vec_vmulesh(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosh(__a, __b);
+#else
   return __builtin_altivec_vmulesh(__a, __b);
+#endif
 }
 
 /* vec_vmuleuh */
@@ -3540,7 +3574,11 @@
 static vector unsigned int __attribute__((__always_inline__))
 vec_vmuleuh(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulouh(__a, __b);
+#else
   return __builtin_altivec_vmuleuh(__a, __b);
+#endif
 }
 
 /* vec_mulo */
@@ -3548,25 +3586,41 @@
 static vector short __ATTRS_o_ai
 vec_mulo(vector signed char __a, vector signed char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesb(__a, __b);
+#else
   return __builtin_altivec_vmulosb(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_mulo(vector unsigned char __a, vector unsigned char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleub(__a, __b);
+#else
   return __builtin_altivec_vmuloub(__a, __b);
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_mulo(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesh(__a, __b);
+#else
   return __builtin_altivec_vmulosh(__a, __b);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_mulo(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleuh(__a, __b);
+#else
   return __builtin_altivec_vmulouh(__a, __b);
+#endif
 }
 
 /* vec_vmulosb */
@@ -3574,7 +3628,11 @@
 static vector short __attribute__((__always_inline__))
 vec_vmulosb(vector signed char __a, vector signed char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesb(__a, __b);
+#else
   return __builtin_altivec_vmulosb(__a, __b);
+#endif
 }
 
 /* vec_vmuloub */
@@ -3582,7 +3640,11 @@
 static vector unsigned short __attribute__((__always_inline__))
 vec_vmuloub(vector unsigned char __a, vector unsigned char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleub(__a, __b);
+#else
   return __builtin_altivec_vmuloub(__a, __b);
+#endif
 }
 
 /* vec_vmulosh */
@@ -3590,7 +3652,11 @@
 static vector int __attribute__((__always_inline__))
 vec_vmulosh(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesh(__a, __b);
+#else
   return __builtin_altivec_vmulosh(__a, __b);
+#endif
 }
 
 /* vec_vmulouh */
@@ -3598,7 +3664,11 @@
 static vector unsigned int __attribute__((__always_inline__))
 vec_vmulouh(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleuh(__a, __b);
+#else
   return __builtin_altivec_vmulouh(__a, __b);
+#endif
 }
 
 /* vec_nmsub */
@@ -4047,52 +4117,91 @@
 
 /* vec_pack */
 
+/* The various vector pack instructions have a big-endian bias, so for
+   little endian we must handle reversed element numbering.  */
+
 static vector signed char __ATTRS_o_ai
 vec_pack(vector signed short __a, vector signed short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_pack(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector bool char __ATTRS_o_ai
 vec_pack(vector bool short __a, vector bool short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector short __ATTRS_o_ai
 vec_pack(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_pack(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_pack(vector bool int __a, vector bool int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 /* vec_vpkuhum */
@@ -4102,25 +4211,43 @@
 static vector signed char __ATTRS_o_ai
 vec_vpkuhum(vector signed short __a, vector signed short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_vpkuhum(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector bool char __ATTRS_o_ai
 vec_vpkuhum(vector bool short __a, vector bool short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 /* vec_vpkuwum */
@@ -4130,25 +4257,43 @@
 static vector short __ATTRS_o_ai
 vec_vpkuwum(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_vpkuwum(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_vpkuwum(vector bool int __a, vector bool int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 /* vec_packpx */
@@ -4156,7 +4301,11 @@
 static vector pixel __attribute__((__always_inline__))
 vec_packpx(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector pixel)__builtin_altivec_vpkpx(__b, __a);
+#else
   return (vector pixel)__builtin_altivec_vpkpx(__a, __b);
+#endif
 }
 
 /* vec_vpkpx */
@@ -4164,7 +4313,11 @@
 static vector pixel __attribute__((__always_inline__))
 vec_vpkpx(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector pixel)__builtin_altivec_vpkpx(__b, __a);
+#else
   return (vector pixel)__builtin_altivec_vpkpx(__a, __b);
+#endif
 }
 
 /* vec_packs */
@@ -4172,25 +4325,41 @@
 static vector signed char __ATTRS_o_ai
 vec_packs(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshss(__b, __a);
+#else
   return __builtin_altivec_vpkshss(__a, __b);
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_packs(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
   return __builtin_altivec_vpkuhus(__a, __b);
+#endif
 }
 
 static vector signed short __ATTRS_o_ai
 vec_packs(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswss(__b, __a);
+#else
   return __builtin_altivec_vpkswss(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_packs(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
   return __builtin_altivec_vpkuwus(__a, __b);
+#endif
 }
 
 /* vec_vpkshss */
@@ -4198,7 +4367,11 @@
 static vector signed char __attribute__((__always_inline__))
 vec_vpkshss(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshss(__b, __a);
+#else
   return __builtin_altivec_vpkshss(__a, __b);
+#endif
 }
 
 /* vec_vpkuhus */
@@ -4206,7 +4379,11 @@
 static vector unsigned char __attribute__((__always_inline__))
 vec_vpkuhus(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
   return __builtin_altivec_vpkuhus(__a, __b);
+#endif
 }
 
 /* vec_vpkswss */
@@ -4214,7 +4391,11 @@
 static vector signed short __attribute__((__always_inline__))
 vec_vpkswss(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswss(__b, __a);
+#else
   return __builtin_altivec_vpkswss(__a, __b);
+#endif
 }
 
 /* vec_vpkuwus */
@@ -4222,7 +4403,11 @@
 static vector unsigned short __attribute__((__always_inline__))
 vec_vpkuwus(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
   return __builtin_altivec_vpkuwus(__a, __b);
+#endif
 }
 
 /* vec_packsu */
@@ -4230,25 +4415,41 @@
 static vector unsigned char __ATTRS_o_ai
 vec_packsu(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshus(__b, __a);
+#else
   return __builtin_altivec_vpkshus(__a, __b);
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_packsu(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
   return __builtin_altivec_vpkuhus(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_packsu(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswus(__b, __a);
+#else
   return __builtin_altivec_vpkswus(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_packsu(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
   return __builtin_altivec_vpkuwus(__a, __b);
+#endif
 }
 
 /* vec_vpkshus */
@@ -4256,13 +4457,21 @@
 static vector unsigned char __ATTRS_o_ai
 vec_vpkshus(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshus(__b, __a);
+#else
   return __builtin_altivec_vpkshus(__a, __b);
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_vpkshus(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
   return __builtin_altivec_vpkuhus(__a, __b);
+#endif
 }
 
 /* vec_vpkswus */
@@ -4270,22 +4479,46 @@
 static vector unsigned short __ATTRS_o_ai
 vec_vpkswus(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswus(__b, __a);
+#else
   return __builtin_altivec_vpkswus(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_vpkswus(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
   return __builtin_altivec_vpkuwus(__a, __b);
+#endif
 }
 
 /* vec_perm */
 
+// The vperm instruction is defined architecturally with a big-endian bias.
+// For little endian, we swap the input operands and invert the permute
+// control vector.  Only the rightmost 5 bits matter, so we could use
+// a vector of all 31s instead of all 255s to perform the inversion.
+// However, when the PCV is not a constant, using 255 has an advantage
+// in that the vec_xor can be recognized as a vec_nor (and for P8 and
+// later, possibly a vec_nand).
+
 vector signed char __ATTRS_o_ai
 vec_perm(vector signed char __a, vector signed char __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector signed char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector signed char)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector unsigned char __ATTRS_o_ai
@@ -4293,22 +4526,46 @@
          vector unsigned char __b,
          vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector unsigned char)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector bool char __ATTRS_o_ai
 vec_perm(vector bool char __a, vector bool char __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector bool char)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector short __ATTRS_o_ai
 vec_perm(vector short __a, vector short __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector short)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector unsigned short __ATTRS_o_ai
@@ -4316,49 +4573,104 @@
          vector unsigned short __b,
          vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector unsigned short)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector bool short __ATTRS_o_ai
 vec_perm(vector bool short __a, vector bool short __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector bool short)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector pixel __ATTRS_o_ai
 vec_perm(vector pixel __a, vector pixel __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector pixel)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector pixel)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector int __ATTRS_o_ai
 vec_perm(vector int __a, vector int __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector int)__builtin_altivec_vperm_4si(__b, __a, __d);
+#else
   return (vector int)__builtin_altivec_vperm_4si(__a, __b, __c);
+#endif
 }
 
 vector unsigned int __ATTRS_o_ai
 vec_perm(vector unsigned int __a, vector unsigned int __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned int)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector unsigned int)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector bool int __ATTRS_o_ai
 vec_perm(vector bool int __a, vector bool int __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool int)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector bool int)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector float __ATTRS_o_ai
 vec_perm(vector float __a, vector float __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector float)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector float)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 /* vec_vperm */
@@ -4366,8 +4678,7 @@
 static vector signed char __ATTRS_o_ai
 vec_vperm(vector signed char __a, vector signed char __b, vector unsigned char __c)
 {
-  return (vector signed char)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector unsigned char __ATTRS_o_ai
@@ -4375,22 +4686,19 @@
           vector unsigned char __b,
           vector unsigned char __c)
 {
-  return (vector unsigned char)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector bool char __ATTRS_o_ai
 vec_vperm(vector bool char __a, vector bool char __b, vector unsigned char __c)
 {
-  return (vector bool char)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector short __ATTRS_o_ai
 vec_vperm(vector short __a, vector short __b, vector unsigned char __c)
 {
-  return (vector short)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector unsigned short __ATTRS_o_ai
@@ -4398,49 +4706,43 @@
           vector unsigned short __b,
           vector unsigned char __c)
 {
-  return (vector unsigned short)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector bool short __ATTRS_o_ai
 vec_vperm(vector bool short __a, vector bool short __b, vector unsigned char __c)
 {
-  return (vector bool short)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector pixel __ATTRS_o_ai
 vec_vperm(vector pixel __a, vector pixel __b, vector unsigned char __c)
 {
-  return (vector pixel)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector int __ATTRS_o_ai
 vec_vperm(vector int __a, vector int __b, vector unsigned char __c)
 {
-  return (vector int)__builtin_altivec_vperm_4si(__a, __b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_vperm(vector unsigned int __a, vector unsigned int __b, vector unsigned char __c)
 {
-  return (vector unsigned int)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector bool int __ATTRS_o_ai
 vec_vperm(vector bool int __a, vector bool int __b, vector unsigned char __c)
 {
-  return (vector bool int)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector float __ATTRS_o_ai
 vec_vperm(vector float __a, vector float __b, vector unsigned char __c)
 {
-  return (vector float)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 /* vec_re */
@@ -4922,65 +5224,113 @@
 static vector signed char __ATTRS_o_ai
 vec_sld(vector signed char __a, vector signed char __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_sld(vector unsigned char __a, vector unsigned char __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector short __ATTRS_o_ai
 vec_sld(vector short __a, vector short __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_sld(vector unsigned short __a, vector unsigned short __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector pixel __ATTRS_o_ai
 vec_sld(vector pixel __a, vector pixel __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_sld(vector int __a, vector int __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_sld(vector unsigned int __a, vector unsigned int __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector float __ATTRS_o_ai
 vec_sld(vector float __a, vector float __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 /* vec_vsldoi */
@@ -4988,65 +5338,113 @@
 static vector signed char __ATTRS_o_ai
 vec_vsldoi(vector signed char __a, vector signed char __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_vsldoi(vector unsigned char __a, vector unsigned char __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector short __ATTRS_o_ai
 vec_vsldoi(vector short __a, vector short __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_vsldoi(vector unsigned short __a, vector unsigned short __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector pixel __ATTRS_o_ai
 vec_vsldoi(vector pixel __a, vector pixel __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_vsldoi(vector int __a, vector int __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_vsldoi(vector unsigned int __a, vector unsigned int __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 static vector float __ATTRS_o_ai
 vec_vsldoi(vector float __a, vector float __b, unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c-1, __c-2, __c-3, __c-4, __c-5, __c-6, __c-7,
+     __c-8, __c-9, __c-10, __c-11, __c-12, __c-13, __c-14, __c-15));
+#else
   return vec_perm(__a, __b, (vector unsigned char)
     (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
      __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+#endif
 }
 
 /* vec_sll */
@@ -8054,10 +8452,26 @@
 
 /* vec_sum2s */
 
+/* The vsum2sws instruction has a big-endian bias, so that the second
+   input vector and the result always reference big-endian elements
+   1 and 3 (little-endian element 0 and 2).  For ease of porting the
+   programmer wants elements 1 and 3 in both cases, so for little
+   endian we must perform some permutes.  */
+
 static vector signed int __attribute__((__always_inline__))
 vec_sum2s(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector int __c = (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+  __c = __builtin_altivec_vsum2sws(__a, __c);
+  return (vector signed int)
+    vec_perm(__c, __c, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+#else
   return __builtin_altivec_vsum2sws(__a, __b);
+#endif
 }
 
 /* vec_vsum2sws */
@@ -8065,15 +8479,41 @@
 static vector signed int __attribute__((__always_inline__))
 vec_vsum2sws(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector int __c = (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+  __c = __builtin_altivec_vsum2sws(__a, __c);
+  return (vector signed int)
+    vec_perm(__c, __c, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+#else
   return __builtin_altivec_vsum2sws(__a, __b);
+#endif
 }
 
 /* vec_sums */
 
+/* The vsumsws instruction has a big-endian bias, so that the second
+   input vector and the result always reference big-endian element 3
+   (little-endian element 0).  For ease of porting the programmer
+   wants element 3 in both cases, so for little endian we must perform
+   some permutes.  */
+
 static vector signed int __attribute__((__always_inline__))
 vec_sums(vector signed int __a, vector signed int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  __b = (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (12,13,14,15,0,1,2,3,4,5,6,7,8,9,10,11));
+  __b = __builtin_altivec_vsumsws(__a, __b);
+  return (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (4,5,6,7,8,9,10,11,12,13,14,15,0,1,2,3));
+#else
   return __builtin_altivec_vsumsws(__a, __b);
+#endif
 }
 
 /* vec_vsumsws */
@@ -8081,7 +8521,17 @@
 static vector signed int __attribute__((__always_inline__))
 vec_vsumsws(vector signed int __a, vector signed int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  __b = (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (12,13,14,15,0,1,2,3,4,5,6,7,8,9,10,11));
+  __b = __builtin_altivec_vsumsws(__a, __b);
+  return (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (4,5,6,7,8,9,10,11,12,13,14,15,0,1,2,3));
+#else
   return __builtin_altivec_vsumsws(__a, __b);
+#endif
 }
 
 /* vec_trunc */
@@ -8102,34 +8552,57 @@
 
 /* vec_unpackh */
 
+/* The vector unpack instructions all have a big-endian bias, so for
+   little endian we must reverse the meanings of "high" and "low."  */
+
 static vector short __ATTRS_o_ai
 vec_unpackh(vector signed char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsb((vector char)__a);
+#else
   return __builtin_altivec_vupkhsb((vector char)__a);
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_unpackh(vector bool char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#else
   return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_unpackh(vector short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsh(__a);
+#else
   return __builtin_altivec_vupkhsh(__a);
+#endif
 }
 
 static vector bool int __ATTRS_o_ai
 vec_unpackh(vector bool short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#else
   return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_unpackh(vector pixel __a)
 {
-  return (vector unsigned int)__builtin_altivec_vupkhsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#endif
 }
 
 /* vec_vupkhsb */
@@ -8137,13 +8610,21 @@
 static vector short __ATTRS_o_ai
 vec_vupkhsb(vector signed char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsb((vector char)__a);
+#else
   return __builtin_altivec_vupkhsb((vector char)__a);
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_vupkhsb(vector bool char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#else
   return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#endif
 }
 
 /* vec_vupkhsh */
@@ -8151,19 +8632,31 @@
 static vector int __ATTRS_o_ai
 vec_vupkhsh(vector short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsh(__a);
+#else
   return __builtin_altivec_vupkhsh(__a);
+#endif
 }
 
 static vector bool int __ATTRS_o_ai
 vec_vupkhsh(vector bool short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#else
   return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_vupkhsh(vector pixel __a)
 {
-  return (vector unsigned int)__builtin_altivec_vupkhsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#endif
 }
 
 /* vec_unpackl */
@@ -8171,31 +8664,51 @@
 static vector short __ATTRS_o_ai
 vec_unpackl(vector signed char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsb((vector char)__a);
+#else
   return __builtin_altivec_vupklsb((vector char)__a);
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_unpackl(vector bool char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#else
   return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_unpackl(vector short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsh(__a);
+#else
   return __builtin_altivec_vupklsh(__a);
+#endif
 }
 
 static vector bool int __ATTRS_o_ai
 vec_unpackl(vector bool short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#else
   return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_unpackl(vector pixel __a)
 {
-  return (vector unsigned int)__builtin_altivec_vupklsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#endif
 }
 
 /* vec_vupklsb */
@@ -8203,13 +8716,21 @@
 static vector short __ATTRS_o_ai
 vec_vupklsb(vector signed char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsb((vector char)__a);
+#else
   return __builtin_altivec_vupklsb((vector char)__a);
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_vupklsb(vector bool char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#else
   return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#endif
 }
 
 /* vec_vupklsh */
@@ -8217,19 +8738,31 @@
 static vector int __ATTRS_o_ai
 vec_vupklsh(vector short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsh(__a);
+#else
   return __builtin_altivec_vupklsh(__a);
+#endif
 }
 
 static vector bool int __ATTRS_o_ai
 vec_vupklsh(vector bool short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#else
   return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_vupklsh(vector pixel __a)
 {
-  return (vector unsigned int)__builtin_altivec_vupklsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#endif
 }
 
 /* vec_xor */
diff --git a/lib/Headers/arm_acle.h b/lib/Headers/arm_acle.h
new file mode 100644
index 0000000..d706745
--- /dev/null
+++ b/lib/Headers/arm_acle.h
@@ -0,0 +1,151 @@
+/*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __ARM_ACLE_H
+#define __ARM_ACLE_H
+
+#ifndef __ARM_ACLE
+#error "ACLE intrinsics support not enabled."
+#endif
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Miscellaneous data-processing intrinsics */
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __clz(uint32_t t) {
+  return __builtin_clz(t);
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+  __clzl(unsigned long t) {
+  return __builtin_clzl(t);
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+  __clzll(uint64_t t) {
+#if __SIZEOF_LONG_LONG__ == 8
+  return __builtin_clzll(t);
+#else
+  return __builtin_clzl(t);
+#endif
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __rev(uint32_t t) {
+  return __builtin_bswap32(t);
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+  __revl(unsigned long t) {
+#if __SIZEOF_LONG__ == 4
+  return __builtin_bswap32(t);
+#else
+  return __builtin_bswap64(t);
+#endif
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+  __revll(uint64_t t) {
+  return __builtin_bswap64(t);
+}
+
+
+/*
+ * Saturating intrinsics
+ *
+ * FIXME: Change guard to their corrosponding __ARM_FEATURE flag when Q flag
+ * intrinsics are implemented and the flag is enabled.
+ */
+#if __ARM_32BIT_STATE
+#define __ssat(x, y) __builtin_arm_ssat(x, y)
+#define __usat(x, y) __builtin_arm_usat(x, y)
+
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+  __qadd(int32_t t, int32_t v) {
+  return __builtin_arm_qadd(t, v);
+}
+
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+  __qsub(int32_t t, int32_t v) {
+  return __builtin_arm_qsub(t, v);
+}
+
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+__qdbl(int32_t t) {
+  return __builtin_arm_qadd(t, t);
+}
+#endif
+
+/* CRC32 intrinsics */
+#if __ARM_FEATURE_CRC32
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32b(uint32_t a, uint8_t b) {
+  return __builtin_arm_crc32b(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32h(uint32_t a, uint16_t b) {
+  return __builtin_arm_crc32h(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32w(uint32_t a, uint32_t b) {
+  return __builtin_arm_crc32w(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32d(uint32_t a, uint64_t b) {
+  return __builtin_arm_crc32d(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cb(uint32_t a, uint8_t b) {
+  return __builtin_arm_crc32cb(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32ch(uint32_t a, uint16_t b) {
+  return __builtin_arm_crc32ch(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cw(uint32_t a, uint32_t b) {
+  return __builtin_arm_crc32cw(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cd(uint32_t a, uint64_t b) {
+  return __builtin_arm_crc32cd(a, b);
+}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ARM_ACLE_H */
diff --git a/lib/Headers/avxintrin.h b/lib/Headers/avxintrin.h
index 3d50439..4e1044a 100644
--- a/lib/Headers/avxintrin.h
+++ b/lib/Headers/avxintrin.h
@@ -737,19 +737,22 @@
 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_broadcast_ss(float const *__a)
 {
-  return (__m128)__builtin_ia32_vbroadcastss(__a);
+  float __f = *__a;
+  return (__m128)(__v4sf){ __f, __f, __f, __f };
 }
 
 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
 _mm256_broadcast_sd(double const *__a)
 {
-  return (__m256d)__builtin_ia32_vbroadcastsd256(__a);
+  double __d = *__a;
+  return (__m256d)(__v4df){ __d, __d, __d, __d };
 }
 
 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
 _mm256_broadcast_ss(float const *__a)
 {
-  return (__m256)__builtin_ia32_vbroadcastss256(__a);
+  float __f = *__a;
+  return (__m256)(__v8sf){ __f, __f, __f, __f, __f, __f, __f, __f };
 }
 
 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
diff --git a/lib/Headers/bmiintrin.h b/lib/Headers/bmiintrin.h
index 8cb00f5..43c4a5e 100644
--- a/lib/Headers/bmiintrin.h
+++ b/lib/Headers/bmiintrin.h
@@ -32,6 +32,14 @@
 #ifndef __BMIINTRIN_H
 #define __BMIINTRIN_H
 
+#define _tzcnt_u16(a)     (__tzcnt_u16((a)))
+#define _andn_u32(a, b)   (__andn_u32((a), (b)))
+/* _bextr_u32 != __bextr_u32 */
+#define _blsi_u32(a)      (__blsi_u32((a)))
+#define _blsmsk_u32(a)    (__blsmsk_u32((a)))
+#define _blsr_u32(a)      (__blsr_u32((a)))
+#define _tzcnt_u32(a)     (__tzcnt_u32((a)))
+
 static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
 __tzcnt_u16(unsigned short __X)
 {
@@ -44,12 +52,20 @@
   return ~__X & __Y;
 }
 
+/* AMD-specified, double-leading-underscore version of BEXTR */
 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
 __bextr_u32(unsigned int __X, unsigned int __Y)
 {
   return __builtin_ia32_bextr_u32(__X, __Y);
 }
 
+/* Intel-specified, single-leading-underscore version of BEXTR */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_bextr_u32(unsigned int __X, unsigned int __Y, unsigned int __Z)
+{
+  return __builtin_ia32_bextr_u32 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
+}
+
 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
 __blsi_u32(unsigned int __X)
 {
@@ -75,18 +91,34 @@
 }
 
 #ifdef __x86_64__
+
+#define _andn_u64(a, b)   (__andn_u64((a), (b)))
+/* _bextr_u64 != __bextr_u64 */
+#define _blsi_u64(a)      (__blsi_u64((a)))
+#define _blsmsk_u64(a)    (__blsmsk_u64((a)))
+#define _blsr_u64(a)      (__blsr_u64((a)))
+#define _tzcnt_u64(a)     (__tzcnt_u64((a)))
+
 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
 __andn_u64 (unsigned long long __X, unsigned long long __Y)
 {
   return ~__X & __Y;
 }
 
+/* AMD-specified, double-leading-underscore version of BEXTR */
 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
 __bextr_u64(unsigned long long __X, unsigned long long __Y)
 {
   return __builtin_ia32_bextr_u64(__X, __Y);
 }
 
+/* Intel-specified, single-leading-underscore version of BEXTR */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_bextr_u64(unsigned long long __X, unsigned int __Y, unsigned int __Z)
+{
+  return __builtin_ia32_bextr_u64 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
+}
+
 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
 __blsi_u64(unsigned long long __X)
 {
@@ -110,6 +142,7 @@
 {
   return __builtin_ctzll(__X);
 }
-#endif
+
+#endif /* __x86_64__ */
 
 #endif /* __BMIINTRIN_H */
diff --git a/lib/Headers/ia32intrin.h b/lib/Headers/ia32intrin.h
index 55c2247..5adf3f1 100644
--- a/lib/Headers/ia32intrin.h
+++ b/lib/Headers/ia32intrin.h
@@ -79,6 +79,11 @@
 }
 #endif /* !__x86_64__ */
 
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rdpmc(int __A) {
+  return __builtin_ia32_rdpmc(__A);
+}
+
 /* __rdtsc */
 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
 __rdtsc(void) {
diff --git a/lib/Headers/stdarg.h b/lib/Headers/stdarg.h
index 6110a06..a57e183 100644
--- a/lib/Headers/stdarg.h
+++ b/lib/Headers/stdarg.h
@@ -44,7 +44,9 @@
 #endif
 
 /* Hack required to make standard headers work, at least on Ubuntu */
+#ifndef __GNUC_VA_LIST
 #define __GNUC_VA_LIST 1
+#endif
 typedef __builtin_va_list __gnuc_va_list;
 
 #endif /* __STDARG_H */
diff --git a/lib/Headers/x86intrin.h b/lib/Headers/x86intrin.h
index be9e71d..21a43da 100644
--- a/lib/Headers/x86intrin.h
+++ b/lib/Headers/x86intrin.h
@@ -76,6 +76,6 @@
 #include <f16cintrin.h>
 #endif
 
-// FIXME: LWP
+/* FIXME: LWP */
 
 #endif /* __X86INTRIN_H */
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
index e777ec0..c9befcb 100644
--- a/lib/Headers/xmmintrin.h
+++ b/lib/Headers/xmmintrin.h
@@ -34,8 +34,8 @@
 typedef float __v4sf __attribute__((__vector_size__(16)));
 typedef float __m128 __attribute__((__vector_size__(16)));
 
-// This header should only be included in a hosted environment as it depends on
-// a standard library to provide allocation routines.
+/* This header should only be included in a hosted environment as it depends on
+ * a standard library to provide allocation routines. */
 #if __STDC_HOSTED__
 #include <mm_malloc.h>
 #endif
@@ -589,7 +589,7 @@
   return (__m128){ __w, __w, __w, __w };
 }
 
-// Microsoft specific.
+/* Microsoft specific. */
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_set_ps1(float __w)
 {
diff --git a/lib/Index/SimpleFormatContext.h b/lib/Index/SimpleFormatContext.h
index 147323a..a460863 100644
--- a/lib/Index/SimpleFormatContext.h
+++ b/lib/Index/SimpleFormatContext.h
@@ -37,7 +37,7 @@
   SimpleFormatContext(LangOptions Options)
       : DiagOpts(new DiagnosticOptions()),
         Diagnostics(new DiagnosticsEngine(new DiagnosticIDs,
-                                          DiagOpts.getPtr())),
+                                          DiagOpts.get())),
         Files((FileSystemOptions())),
         Sources(*Diagnostics, Files),
         Rewrite(Sources, Options) {
@@ -47,8 +47,7 @@
   ~SimpleFormatContext() { }
 
   FileID createInMemoryFile(StringRef Name, StringRef Content) {
-    const llvm::MemoryBuffer *Source =
-        llvm::MemoryBuffer::getMemBuffer(Content);
+    llvm::MemoryBuffer *Source = llvm::MemoryBuffer::getMemBuffer(Content);
     const FileEntry *Entry =
         Files.getVirtualFile(Name, Source->getBufferSize(), 0);
     Sources.overrideFileContents(Entry, Source);
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 7554bc6..c7740be 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -824,7 +824,7 @@
   if (ShouldGenerateLocation)
     printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
   Out << "@macro@";
-  Out << MD->getName()->getNameStart();
+  Out << MD->getName()->getName();
   return false;
 }
 
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index a1dbe49..c12d731 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -666,9 +666,7 @@
         // Otherwise, we found the path via MSVC header search rules.  If
         // -Wmsvc-include is enabled, we have to keep searching to see if we
         // would've found this header in -I or -isystem directories.
-        if (Diags.getDiagnosticLevel(diag::ext_pp_include_search_ms,
-                                     IncludeLoc) ==
-            DiagnosticsEngine::Ignored) {
+        if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
           return FE;
         } else {
           MSFE = FE;
@@ -1275,7 +1273,7 @@
   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
     bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
     if (SearchDirs[Idx].isFramework()) {
-      llvm::error_code EC;
+      std::error_code EC;
       SmallString<128> DirNative;
       llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
                               DirNative);
@@ -1335,8 +1333,8 @@
 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
   if (SearchDir.haveSearchedAllModuleMaps())
     return;
-  
-  llvm::error_code EC;
+
+  std::error_code EC;
   SmallString<128> DirNative;
   llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
   for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 21b51e1..6f6b50b 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -1399,8 +1399,7 @@
 static void maybeDiagnoseIDCharCompat(DiagnosticsEngine &Diags, uint32_t C,
                                       CharSourceRange Range, bool IsFirst) {
   // Check C99 compatibility.
-  if (Diags.getDiagnosticLevel(diag::warn_c99_compat_unicode_id,
-                               Range.getBegin()) > DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_c99_compat_unicode_id, Range.getBegin())) {
     enum {
       CannotAppearInIdentifier = 0,
       CannotStartIdentifier
@@ -1422,8 +1421,7 @@
   }
 
   // Check C++98 compatibility.
-  if (Diags.getDiagnosticLevel(diag::warn_cxx98_compat_unicode_id,
-                               Range.getBegin()) > DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_cxx98_compat_unicode_id, Range.getBegin())) {
     static const llvm::sys::UnicodeCharSet CXX03AllowedIDChars(
         CXX03AllowedIDCharRanges);
     if (!CXX03AllowedIDChars.contains(C)) {
@@ -2522,8 +2520,7 @@
       // C++11 [lex.phases] 2.2 p2
       // Prefer the C++98 pedantic compatibility warning over the generic,
       // non-extension, user-requested "missing newline at EOF" warning.
-      if (Diags.getDiagnosticLevel(diag::warn_cxx98_compat_no_newline_eof,
-                                   EndLoc) != DiagnosticsEngine::Ignored) {
+      if (!Diags.isIgnored(diag::warn_cxx98_compat_no_newline_eof, EndLoc)) {
         DiagID = diag::warn_cxx98_compat_no_newline_eof;
       } else {
         DiagID = diag::warn_no_newline_eof;
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 8550198..6417d0f 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -522,7 +522,7 @@
   isLongLong = false;
   isFloat = false;
   isImaginary = false;
-  isMicrosoftInteger = false;
+  MicrosoftInteger = 0;
   hadError = false;
 
   if (*s == '0') { // parse radix
@@ -606,49 +606,53 @@
     case 'i':
     case 'I':
       if (PP.getLangOpts().MicrosoftExt) {
-        if (isFPConstant || isLong || isLongLong) break;
+        if (isLong || isLongLong || MicrosoftInteger)
+          break;
 
         // Allow i8, i16, i32, i64, and i128.
         if (s + 1 != ThisTokEnd) {
           switch (s[1]) {
             case '8':
+              if (isFPConstant) break;
               s += 2; // i8 suffix
-              isMicrosoftInteger = true;
+              MicrosoftInteger = 8;
               break;
             case '1':
+              if (isFPConstant) break;
               if (s + 2 == ThisTokEnd) break;
               if (s[2] == '6') {
                 s += 3; // i16 suffix
-                isMicrosoftInteger = true;
+                MicrosoftInteger = 16;
               }
               else if (s[2] == '2') {
                 if (s + 3 == ThisTokEnd) break;
                 if (s[3] == '8') {
                   s += 4; // i128 suffix
-                  isMicrosoftInteger = true;
+                  MicrosoftInteger = 128;
                 }
               }
               break;
             case '3':
+              if (isFPConstant) break;
               if (s + 2 == ThisTokEnd) break;
               if (s[2] == '2') {
                 s += 3; // i32 suffix
-                isLong = true;
-                isMicrosoftInteger = true;
+                MicrosoftInteger = 32;
               }
               break;
             case '6':
+              if (isFPConstant) break;
               if (s + 2 == ThisTokEnd) break;
               if (s[2] == '4') {
                 s += 3; // i64 suffix
-                isLongLong = true;
-                isMicrosoftInteger = true;
+                MicrosoftInteger = 64;
               }
               break;
             default:
               break;
           }
-          break;
+          if (MicrosoftInteger)
+            break;
         }
       }
       // "i", "if", and "il" are user-defined suffixes in C++1y.
@@ -677,7 +681,7 @@
       isLongLong = false;
       isFloat = false;
       isImaginary = false;
-      isMicrosoftInteger = false;
+      MicrosoftInteger = 0;
 
       saw_ud_suffix = true;
       return;
@@ -1251,26 +1255,26 @@
 /// \endverbatim
 ///
 StringLiteralParser::
-StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+StringLiteralParser(ArrayRef<Token> StringToks,
                     Preprocessor &PP, bool Complain)
   : SM(PP.getSourceManager()), Features(PP.getLangOpts()),
     Target(PP.getTargetInfo()), Diags(Complain ? &PP.getDiagnostics() :nullptr),
     MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
     ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
-  init(StringToks, NumStringToks);
+  init(StringToks);
 }
 
-void StringLiteralParser::init(const Token *StringToks, unsigned NumStringToks){
+void StringLiteralParser::init(ArrayRef<Token> StringToks){
   // The literal token may have come from an invalid source location (e.g. due
   // to a PCH error), in which case the token length will be 0.
-  if (NumStringToks == 0 || StringToks[0].getLength() < 2)
+  if (StringToks.empty() || StringToks[0].getLength() < 2)
     return DiagnoseLexingError(SourceLocation());
 
   // Scan all of the string portions, remember the max individual token length,
   // computing a bound on the concatenated string length, and see whether any
   // piece is a wide-string.  If any of the string portions is a wide-string
   // literal, the result is a wide-string literal [C99 6.4.5p4].
-  assert(NumStringToks && "expected at least one token");
+  assert(!StringToks.empty() && "expected at least one token");
   MaxTokenLength = StringToks[0].getLength();
   assert(StringToks[0].getLength() >= 2 && "literal token is invalid!");
   SizeBound = StringToks[0].getLength()-2;  // -2 for "".
@@ -1280,7 +1284,7 @@
 
   // Implement Translation Phase #6: concatenation of string literals
   /// (C99 5.1.1.2p1).  The common case is only one string fragment.
-  for (unsigned i = 1; i != NumStringToks; ++i) {
+  for (unsigned i = 1; i != StringToks.size(); ++i) {
     if (StringToks[i].getLength() < 2)
       return DiagnoseLexingError(StringToks[i].getLocation());
 
@@ -1336,7 +1340,7 @@
 
   SourceLocation UDSuffixTokLoc;
 
-  for (unsigned i = 0, e = NumStringToks; i != e; ++i) {
+  for (unsigned i = 0, e = StringToks.size(); i != e; ++i) {
     const char *ThisTokBuf = &TokenBuf[0];
     // Get the spelling of the token, which eliminates trigraphs, etc.  We know
     // that ThisTokBuf points to a buffer that is big enough for the whole token
@@ -1510,10 +1514,10 @@
     // Verify that pascal strings aren't too large.
     if (GetStringLength() > 256) {
       if (Diags)
-        Diags->Report(StringToks[0].getLocation(),
+        Diags->Report(StringToks.front().getLocation(),
                       diag::err_pascal_string_too_long)
-          << SourceRange(StringToks[0].getLocation(),
-                         StringToks[NumStringToks-1].getLocation());
+          << SourceRange(StringToks.front().getLocation(),
+                         StringToks.back().getLocation());
       hadError = true;
       return;
     }
@@ -1522,12 +1526,12 @@
     unsigned MaxChars = Features.CPlusPlus? 65536 : Features.C99 ? 4095 : 509;
 
     if (GetNumStringChars() > MaxChars)
-      Diags->Report(StringToks[0].getLocation(),
+      Diags->Report(StringToks.front().getLocation(),
                     diag::ext_string_too_long)
         << GetNumStringChars() << MaxChars
         << (Features.CPlusPlus ? 2 : Features.C99 ? 1 : 0)
-        << SourceRange(StringToks[0].getLocation(),
-                       StringToks[NumStringToks-1].getLocation());
+        << SourceRange(StringToks.front().getLocation(),
+                       StringToks.back().getLocation());
   }
 }
 
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 0538d33..a6d1d82 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -706,7 +706,7 @@
   Result->InferExportWildcard = true;
   
   // Look for subframeworks.
-  llvm::error_code EC;
+  std::error_code EC;
   SmallString<128> SubframeworksDirName
     = StringRef(FrameworkDir->getName());
   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
@@ -1122,7 +1122,7 @@
 
     // Parse the string literal.
     LangOptions LangOpts;
-    StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
+    StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
     if (StringLiteral.hadError)
       goto retry;
     
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index a7a4bbc..1741c30 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -101,14 +101,13 @@
 /// \brief Release the specified MacroInfo to be reused for allocating
 /// new MacroInfo objects.
 void Preprocessor::ReleaseMacroInfo(MacroInfo *MI) {
-  MacroInfoChain *MIChain = (MacroInfoChain*) MI;
+  MacroInfoChain *MIChain = (MacroInfoChain *)MI;
   if (MacroInfoChain *Prev = MIChain->Prev) {
     MacroInfoChain *Next = MIChain->Next;
     Prev->Next = Next;
     if (Next)
       Next->Prev = Prev;
-  }
-  else {
+  } else {
     assert(MIChainHead == MIChain);
     MIChainHead = MIChain->Next;
     MIChainHead->Prev = nullptr;
@@ -140,22 +139,21 @@
     std::string Spelling = getSpelling(MacroNameTok, &Invalid);
     if (Invalid)
       return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
+    II = getIdentifierInfo(Spelling);
 
-    const IdentifierInfo &Info = Identifiers.get(Spelling);
+    if (!II->isCPlusPlusOperatorKeyword())
+      return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
 
-    // Allow #defining |and| and friends in microsoft mode.
-    if (Info.isCPlusPlusOperatorKeyword() && getLangOpts().MSVCCompat) {
-      MacroNameTok.setIdentifierInfo(getIdentifierInfo(Spelling));
-      return false;
-    }
+    // C++ 2.5p2: Alternative tokens behave the same as its primary token
+    // except for their spellings.
+    Diag(MacroNameTok, getLangOpts().MicrosoftExt
+                           ? diag::ext_pp_operator_used_as_macro_name
+                           : diag::err_pp_operator_used_as_macro_name)
+        << II << MacroNameTok.getKind();
 
-    if (Info.isCPlusPlusOperatorKeyword())
-      // C++ 2.5p2: Alternative tokens behave the same as its primary token
-      // except for their spellings.
-      return Diag(MacroNameTok, diag::err_pp_operator_used_as_macro_name)
-             << Spelling << MacroNameTok.getKind();
-
-    return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
+    // Allow #defining |and| and friends for Microsoft compatibility or
+    // recovery when legacy C headers are included in C++.
+    MacroNameTok.setIdentifierInfo(II);
   }
 
   if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) {
@@ -957,7 +955,7 @@
     return DiscardUntilEndOfDirective();
   } else {
     // Parse and validate the string, converting it into a unique ID.
-    StringLiteralParser Literal(&StrTok, 1, *this);
+    StringLiteralParser Literal(StrTok, *this);
     assert(Literal.isAscii() && "Didn't allow wide strings in");
     if (Literal.hadError)
       return DiscardUntilEndOfDirective();
@@ -1093,7 +1091,7 @@
     return DiscardUntilEndOfDirective();
   } else {
     // Parse and validate the string, converting it into a unique ID.
-    StringLiteralParser Literal(&StrTok, 1, *this);
+    StringLiteralParser Literal(StrTok, *this);
     assert(Literal.isAscii() && "Didn't allow wide strings in");
     if (Literal.hadError)
       return DiscardUntilEndOfDirective();
@@ -2124,8 +2122,7 @@
   // If we need warning for not using the macro, add its location in the
   // warn-because-unused-macro set. If it gets used it will be removed from set.
   if (getSourceManager().isInMainFile(MI->getDefinitionLoc()) &&
-      Diags->getDiagnosticLevel(diag::pp_macro_not_used,
-          MI->getDefinitionLoc()) != DiagnosticsEngine::Ignored) {
+      !Diags->isIgnored(diag::pp_macro_not_used, MI->getDefinitionLoc())) {
     MI->setIsWarnIfUnused(true);
     WarnUnusedMacroLocs.insert(MI->getDefinitionLoc());
   }
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index e79fbe1..22ee971 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -449,26 +449,25 @@
       SourceLocation StartLoc
         = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
 
-      if (getDiagnostics().getDiagnosticLevel(
-            diag::warn_uncovered_module_header, 
-            StartLoc) != DiagnosticsEngine::Ignored) {
+      if (!getDiagnostics().isIgnored(diag::warn_uncovered_module_header,
+                                      StartLoc)) {
         ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
-        typedef llvm::sys::fs::recursive_directory_iterator
-          recursive_directory_iterator;
         const DirectoryEntry *Dir = Mod->getUmbrellaDir();
-        llvm::error_code EC;
-        for (recursive_directory_iterator Entry(Dir->getName(), EC), End;
+        vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+        std::error_code EC;
+        for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End;
              Entry != End && !EC; Entry.increment(EC)) {
           using llvm::StringSwitch;
           
           // Check whether this entry has an extension typically associated with
           // headers.
-          if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->path()))
+          if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->getName()))
                  .Cases(".h", ".H", ".hh", ".hpp", true)
                  .Default(false))
             continue;
 
-          if (const FileEntry *Header = getFileManager().getFile(Entry->path()))
+          if (const FileEntry *Header =
+                  getFileManager().getFile(Entry->getName()))
             if (!getSourceManager().hasFileInfo(Header)) {
               if (!ModMap.isHeaderInUnavailableModule(Header)) {
                 // Find the relative path that would access this header.
@@ -486,9 +485,8 @@
     // mentioned at all in the module map. Such headers 
     SourceLocation StartLoc
       = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
-    if (getDiagnostics().getDiagnosticLevel(diag::warn_forgotten_module_header,
-                                            StartLoc)
-          != DiagnosticsEngine::Ignored) {
+    if (!getDiagnostics().isIgnored(diag::warn_forgotten_module_header,
+                                    StartLoc)) {
       ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
       for (unsigned I = 0, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) {
         // We only care about file entries.
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 57bc946..26b99fa 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -1006,8 +1006,8 @@
 
   // If the use of an extension results in an error diagnostic, extensions are
   // effectively unavailable, so just return false here.
-  if (PP.getDiagnostics().getExtensionHandlingBehavior() ==
-      DiagnosticsEngine::Ext_Error)
+  if (PP.getDiagnostics().getExtensionHandlingBehavior() >=
+      diag::Severity::Error)
     return false;
 
   const LangOptions &LangOpts = PP.getLangOpts();
@@ -1294,6 +1294,7 @@
     }
     Tok.setKind(tok::string_literal);
   } else if (II == Ident__DATE__) {
+    Diag(Tok.getLocation(), diag::warn_pp_date_time);
     if (!DATELoc.isValid())
       ComputeDATE_TIME(DATELoc, TIMELoc, *this);
     Tok.setKind(tok::string_literal);
@@ -1303,6 +1304,7 @@
                                                  Tok.getLength()));
     return;
   } else if (II == Ident__TIME__) {
+    Diag(Tok.getLocation(), diag::warn_pp_date_time);
     if (!TIMELoc.isValid())
       ComputeDATE_TIME(DATELoc, TIMELoc, *this);
     Tok.setKind(tok::string_literal);
@@ -1327,6 +1329,7 @@
     OS << Depth;
     Tok.setKind(tok::numeric_constant);
   } else if (II == Ident__TIMESTAMP__) {
+    Diag(Tok.getLocation(), diag::warn_pp_date_time);
     // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
     // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
 
@@ -1347,7 +1350,7 @@
       Result = "??? ??? ?? ??:??:?? ????\n";
     }
     // Surround the string with " and strip the trailing newline.
-    OS << '"' << StringRef(Result, strlen(Result)-1) << '"';
+    OS << '"' << StringRef(Result).drop_back() << '"';
     Tok.setKind(tok::string_literal);
   } else if (II == Ident__COUNTER__) {
     // __COUNTER__ expands to a simple numeric value.
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index 42629d4..fce31c4 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -25,11 +25,11 @@
 #include "llvm/Support/EndianStream.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/OnDiskHashTable.h"
-#include "llvm/Support/system_error.h"
 #include <memory>
+#include <system_error>
 using namespace clang;
 
-#define DISK_TOKEN_SIZE (1+1+2+4+4)
+static const unsigned StoredTokenSize = 1 + 1 + 2 + 4 + 4;
 
 //===----------------------------------------------------------------------===//
 // PTHLexer methods.
@@ -110,7 +110,7 @@
   }
 
   if (TKind == tok::hash && Tok.isAtStartOfLine()) {
-    LastHashTokPtr = CurPtr - DISK_TOKEN_SIZE;
+    LastHashTokPtr = CurPtr - StoredTokenSize;
     assert(!LexingRawMode);
     PP->HandleDirective(Tok);
 
@@ -179,7 +179,7 @@
     if (y & Token::StartOfLine) break;
 
     // Skip to the next token.
-    p += DISK_TOKEN_SIZE;
+    p += StoredTokenSize;
   }
 
   CurPtr = p;
@@ -255,10 +255,10 @@
   // already points 'elif'.  Just return.
 
   if (CurPtr > HashEntryI) {
-    assert(CurPtr == HashEntryI + DISK_TOKEN_SIZE);
+    assert(CurPtr == HashEntryI + StoredTokenSize);
     // Did we reach a #endif?  If so, go ahead and consume that token as well.
     if (isEndif)
-      CurPtr += DISK_TOKEN_SIZE*2;
+      CurPtr += StoredTokenSize * 2;
     else
       LastHashTokPtr = HashEntryI;
 
@@ -274,10 +274,12 @@
 
   // Skip the '#' token.
   assert(((tok::TokenKind)*CurPtr) == tok::hash);
-  CurPtr += DISK_TOKEN_SIZE;
+  CurPtr += StoredTokenSize;
 
   // Did we reach a #endif?  If so, go ahead and consume that token as well.
-  if (isEndif) { CurPtr += DISK_TOKEN_SIZE*2; }
+  if (isEndif) {
+    CurPtr += StoredTokenSize * 2;
+  }
 
   return isEndif;
 }
@@ -290,7 +292,7 @@
   // NOTE: This is a virtual function; hence it is defined out-of-line.
   using namespace llvm::support;
 
-  const unsigned char *OffsetPtr = CurPtr + (DISK_TOKEN_SIZE - 4);
+  const unsigned char *OffsetPtr = CurPtr + (StoredTokenSize - 4);
   uint32_t Offset = endian::readNext<uint32_t, little, aligned>(OffsetPtr);
   return FileStartLoc.getLocWithOffset(Offset);
 }
@@ -440,13 +442,15 @@
 PTHManager *PTHManager::Create(const std::string &file,
                                DiagnosticsEngine &Diags) {
   // Memory map the PTH file.
-  std::unique_ptr<llvm::MemoryBuffer> File;
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileOrErr =
+      llvm::MemoryBuffer::getFile(file);
 
-  if (llvm::MemoryBuffer::getFile(file, File)) {
+  if (!FileOrErr) {
     // FIXME: Add ec.message() to this diag.
     Diags.Report(diag::err_invalid_pth_file) << file;
     return nullptr;
   }
+  std::unique_ptr<llvm::MemoryBuffer> File = std::move(FileOrErr.get());
 
   using namespace llvm::support;
 
@@ -700,10 +704,9 @@
     Cache(FL.getNumBuckets(), FL.getNumEntries(), FL.getBuckets(),
           FL.getBase()) {}
 
-  ~PTHStatCache() {}
-
   LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                       vfs::File **F, vfs::FileSystem &FS) override {
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override {
     // Do the lookup for the file's data in the PTH file.
     CacheTy::iterator I = Cache.find(Path);
 
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index b837fc5..a5f1a62 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -954,16 +954,7 @@
     IdentifierInfo *II = Tok.getIdentifierInfo();
     PPCallbacks *Callbacks = PP.getPPCallbacks();
 
-    diag::Mapping Map;
-    if (II->isStr("warning"))
-      Map = diag::MAP_WARNING;
-    else if (II->isStr("error"))
-      Map = diag::MAP_ERROR;
-    else if (II->isStr("ignored"))
-      Map = diag::MAP_IGNORE;
-    else if (II->isStr("fatal"))
-      Map = diag::MAP_FATAL;
-    else if (II->isStr("pop")) {
+    if (II->isStr("pop")) {
       if (!PP.getDiagnostics().popMappings(DiagLoc))
         PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
       else if (Callbacks)
@@ -974,7 +965,16 @@
       if (Callbacks)
         Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
       return;
-    } else {
+    }
+
+    diag::Severity SV = llvm::StringSwitch<diag::Severity>(II->getName())
+                            .Case("ignored", diag::Severity::Ignored)
+                            .Case("warning", diag::Severity::Warning)
+                            .Case("error", diag::Severity::Error)
+                            .Case("fatal", diag::Severity::Fatal)
+                            .Default(diag::Severity());
+
+    if (SV == diag::Severity()) {
       PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
       return;
     }
@@ -998,12 +998,12 @@
       return;
     }
 
-    if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.substr(2),
-                                                      Map, DiagLoc))
+    if (PP.getDiagnostics().setSeverityForGroup(WarningName.substr(2), SV,
+                                                DiagLoc))
       PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
         << WarningName;
     else if (Callbacks)
-      Callbacks->PragmaDiagnostic(DiagLoc, Namespace, Map, WarningName);
+      Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);
   }
 };
 
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index b561636..4a11803 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -60,7 +60,7 @@
                            ModuleLoader &TheModuleLoader,
                            IdentifierInfoLookup *IILookup, bool OwnsHeaders,
                            TranslationUnitKind TUKind)
-    : PPOpts(PPOpts), Diags(&diags), LangOpts(opts), Target(0),
+    : PPOpts(PPOpts), Diags(&diags), LangOpts(opts), Target(nullptr),
       FileMgr(Headers.getFileMgr()), SourceMgr(SM), HeaderInfo(Headers),
       TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),
       Identifiers(opts, IILookup), IncrementalProcessing(false), TUKind(TUKind),
@@ -70,7 +70,7 @@
       SkipMainFilePreamble(0, true), CurPPLexer(nullptr),
       CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr),
       Callbacks(nullptr), MacroArgCache(nullptr), Record(nullptr),
-      MIChainHead(nullptr), MICache(nullptr), DeserialMIChainHead(0) {
+      MIChainHead(nullptr), MICache(nullptr), DeserialMIChainHead(nullptr) {
   OwnsHeaderSearch = OwnsHeaders;
   
   ScratchBuf = new ScratchBuffer(SourceMgr);
@@ -757,7 +757,7 @@
   } while (Result.is(tok::string_literal));
 
   // Concatenate and parse the strings.
-  StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
+  StringLiteralParser Literal(StrToks, *this);
   assert(Literal.isAscii() && "Didn't allow wide strings in");
 
   if (Literal.hadError)
diff --git a/lib/Parse/Android.mk b/lib/Parse/Android.mk
index 5bc2200..ff63b60 100644
--- a/lib/Parse/Android.mk
+++ b/lib/Parse/Android.mk
@@ -31,6 +31,7 @@
 	ParseOpenMP.cpp  \
 	ParsePragma.cpp  \
 	ParseStmt.cpp  \
+	ParseStmtAsm.cpp  \
 	ParseTemplate.cpp  \
 	ParseTentative.cpp  \
 	Parser.cpp
diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt
index 10b146f..9933025 100644
--- a/lib/Parse/CMakeLists.txt
+++ b/lib/Parse/CMakeLists.txt
@@ -16,6 +16,7 @@
   ParseOpenMP.cpp
   ParsePragma.cpp
   ParseStmt.cpp
+  ParseStmtAsm.cpp
   ParseTemplate.cpp
   ParseTentative.cpp
   Parser.cpp
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 19aa664..310e2b4 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -349,7 +349,7 @@
                            (*Toks)[Toks->size() - 3].getLocation());
         }
         Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
-                                          DefArgResult.take());
+                                          DefArgResult.get());
       }
 
       assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
@@ -535,7 +535,7 @@
                                               EqualLoc);
 
   Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc,
-                                                 Init.release());
+                                                 Init.get());
 
   // The next token should be our artificial terminating EOF token.
   if (Tok.isNot(tok::eof)) {
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 7507ddf..09f78e5 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -304,7 +304,7 @@
         SkipUntil(tok::r_paren, StopAtSemi);
         return 0;
       }
-      ArgExprs.push_back(ArgExpr.release());
+      ArgExprs.push_back(ArgExpr.get());
       // Eat the comma, move to the next argument
     } while (TryConsumeToken(tok::comma));
   }
@@ -906,7 +906,7 @@
                Changes[Introduced],
                Changes[Deprecated],
                Changes[Obsoleted],
-               UnavailableLoc, MessageExpr.take(),
+               UnavailableLoc, MessageExpr.get(),
                AttributeList::AS_GNU);
 }
 
@@ -1187,7 +1187,7 @@
 
   if (!T.consumeClose()) {
     Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, nullptr, AttrNameLoc,
-                                   ArgumentKind, MatchingCType.release(),
+                                   ArgumentKind, MatchingCType.get(),
                                    LayoutCompatible, MustBeNull,
                                    AttributeList::AS_GNU);
   }
@@ -1699,7 +1699,7 @@
       return true;
     }
 
-    D.setAsmLabel(AsmLabel.release());
+    D.setAsmLabel(AsmLabel.get());
     D.SetRangeEnd(Loc);
   }
 
@@ -1857,7 +1857,7 @@
         SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
         Actions.ActOnInitializerError(ThisDecl);
       } else
-        Actions.AddInitializerToDecl(ThisDecl, Init.take(),
+        Actions.AddInitializerToDecl(ThisDecl, Init.get(),
                                      /*DirectInit=*/false, TypeContainsAuto);
     }
   } else if (Tok.is(tok::l_paren)) {
@@ -1896,7 +1896,7 @@
       ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
                                                           T.getCloseLocation(),
                                                           Exprs);
-      Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
+      Actions.AddInitializerToDecl(ThisDecl, Initializer.get(),
                                    /*DirectInit=*/true, TypeContainsAuto);
     }
   } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
@@ -1919,7 +1919,7 @@
     if (Init.isInvalid()) {
       Actions.ActOnInitializerError(ThisDecl);
     } else
-      Actions.AddInitializerToDecl(ThisDecl, Init.take(),
+      Actions.AddInitializerToDecl(ThisDecl, Init.get(),
                                    /*DirectInit=*/true, TypeContainsAuto);
 
   } else {
@@ -2170,42 +2170,33 @@
     }
   }
 
-  // This is almost certainly an invalid type name. Let the action emit a
-  // diagnostic and attempt to recover.
+  // This is almost certainly an invalid type name. Let Sema emit a diagnostic
+  // and attempt to recover.
   ParsedType T;
   IdentifierInfo *II = Tok.getIdentifierInfo();
-  if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T,
-                                      getLangOpts().CPlusPlus &&
-                                          NextToken().is(tok::less))) {
-    // The action emitted a diagnostic, so we don't have to.
-    if (T) {
-      // The action has suggested that the type T could be used. Set that as
-      // the type in the declaration specifiers, consume the would-be type
-      // name token, and we're done.
-      const char *PrevSpec;
-      unsigned DiagID;
-      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T,
-                         Actions.getASTContext().getPrintingPolicy());
-      DS.SetRangeEnd(Tok.getLocation());
-      ConsumeToken();
-      // There may be other declaration specifiers after this.
-      return true;
-    } else if (II != Tok.getIdentifierInfo()) {
-      // If no type was suggested, the correction is to a keyword
-      Tok.setKind(II->getTokenID());
-      // There may be other declaration specifiers after this.
-      return true;
-    }
-
-    // Fall through; the action had no suggestion for us.
-  } else {
-    // The action did not emit a diagnostic, so emit one now.
-    SourceRange R;
-    if (SS) R = SS->getRange();
-    Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
+  Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T,
+                                  getLangOpts().CPlusPlus &&
+                                      NextToken().is(tok::less));
+  if (T) {
+    // The action has suggested that the type T could be used. Set that as
+    // the type in the declaration specifiers, consume the would-be type
+    // name token, and we're done.
+    const char *PrevSpec;
+    unsigned DiagID;
+    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T,
+                       Actions.getASTContext().getPrintingPolicy());
+    DS.SetRangeEnd(Tok.getLocation());
+    ConsumeToken();
+    // There may be other declaration specifiers after this.
+    return true;
+  } else if (II != Tok.getIdentifierInfo()) {
+    // If no type was suggested, the correction is to a keyword
+    Tok.setKind(II->getTokenID());
+    // There may be other declaration specifiers after this.
+    return true;
   }
 
-  // Mark this as an error.
+  // Otherwise, the action had no suggestion for us.  Mark this as an error.
   DS.SetTypeSpecError();
   DS.SetRangeEnd(Tok.getLocation());
   ConsumeToken();
@@ -2227,6 +2218,8 @@
     return DSC_class;
   if (Context == Declarator::FileContext)
     return DSC_top_level;
+  if (Context == Declarator::TemplateTypeArgContext)
+    return DSC_template_type_arg;
   if (Context == Declarator::TrailingReturnContext)
     return DSC_trailing;
   if (Context == Declarator::AliasDeclContext ||
@@ -2294,7 +2287,7 @@
     *EndLoc = T.getCloseLocation();
 
   ArgsVector ArgExprs;
-  ArgExprs.push_back(ArgExpr.release());
+  ArgExprs.push_back(ArgExpr.get());
   Attrs.addNew(KWName, KWLoc, nullptr, KWLoc, ArgExprs.data(), 1,
                AttributeList::AS_Keyword, EllipsisLoc);
 }
@@ -2753,6 +2746,16 @@
         Actions.getTypeName(*Tok.getIdentifierInfo(),
                             Tok.getLocation(), getCurScope());
 
+      // MSVC: If we weren't able to parse a default template argument, and it's
+      // just a simple identifier, create a DependentNameType.  This will allow us
+      // to defer the name lookup to template instantiation time, as long we forge a
+      // NestedNameSpecifier for the current context.
+      if (!TypeRep && DSContext == DSC_template_type_arg &&
+          getLangOpts().MSVCCompat && getCurScope()->isTemplateParamScope()) {
+        TypeRep = Actions.ActOnDelayedDefaultTemplateArg(
+            *Tok.getIdentifierInfo(), Tok.getLocation());
+      }
+
       // If this is not a typedef name, don't parse it as part of the declspec,
       // it must be an implicit int or an error.
       if (!TypeRep) {
@@ -3261,7 +3264,7 @@
       if (Res.isInvalid())
         SkipUntil(tok::semi, StopBeforeMatch);
       else
-        DeclaratorInfo.BitfieldSize = Res.release();
+        DeclaratorInfo.BitfieldSize = Res.get();
     }
 
     // If attributes exist after the declarator, parse them.
@@ -3768,7 +3771,7 @@
 ///
 void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
   // Enter the scope of the enum body and start the definition.
-  ParseScope EnumScope(this, Scope::DeclScope);
+  ParseScope EnumScope(this, Scope::DeclScope | Scope::EnumScope);
   Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
 
   BalancedDelimiterTracker T(*this, tok::l_brace);
@@ -3817,7 +3820,7 @@
                                                     LastEnumConstDecl,
                                                     IdentLoc, Ident,
                                                     attrs.getList(), EqualLoc,
-                                                    AssignedVal.release());
+                                                    AssignedVal.get());
     PD.complete(EnumConstDecl);
 
     EnumConstantDecls.push_back(EnumConstDecl);
@@ -4661,17 +4664,17 @@
   }
 }
 
-static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
-                                      SourceLocation EllipsisLoc) {
-  if (EllipsisLoc.isValid()) {
-    FixItHint Insertion;
-    if (!D.getEllipsisLoc().isValid()) {
-      Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
-      D.setEllipsisLoc(EllipsisLoc);
-    }
-    P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
-      << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
-  }
+// When correcting from misplaced brackets before the identifier, the location
+// is saved inside the declarator so that other diagnostic messages can use
+// them.  This extracts and returns that location, or returns the provided
+// location if a stored location does not exist.
+static SourceLocation getMissingDeclaratorIdLoc(Declarator &D,
+                                                SourceLocation Loc) {
+  if (D.getName().StartLocation.isInvalid() &&
+      D.getName().EndLocation.isValid())
+    return D.getName().EndLocation;
+
+  return Loc;
 }
 
 /// ParseDirectDeclarator
@@ -4753,7 +4756,8 @@
         // The ellipsis was put in the wrong place. Recover, and explain to
         // the user what they should have done.
         ParseDeclarator(D);
-        diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
+        if (EllipsisLoc.isValid())
+          DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
         return;
       } else
         D.setEllipsisLoc(EllipsisLoc);
@@ -4850,11 +4854,14 @@
   } else {
     if (Tok.getKind() == tok::annot_pragma_parser_crash)
       LLVM_BUILTIN_TRAP;
-    if (D.getContext() == Declarator::MemberContext)
-      Diag(Tok, diag::err_expected_member_name_or_semi)
+    if (Tok.is(tok::l_square))
+      return ParseMisplacedBracketDeclarator(D);
+    if (D.getContext() == Declarator::MemberContext) {
+      Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+           diag::err_expected_member_name_or_semi)
           << (D.getDeclSpec().isEmpty() ? SourceRange()
                                         : D.getDeclSpec().getSourceRange());
-    else if (getLangOpts().CPlusPlus) {
+    } else if (getLangOpts().CPlusPlus) {
       if (Tok.is(tok::period) || Tok.is(tok::arrow))
         Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
       else {
@@ -4863,11 +4870,15 @@
           Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
               << getLangOpts().CPlusPlus;
         else
-          Diag(Tok, diag::err_expected_unqualified_id)
+          Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+               diag::err_expected_unqualified_id)
               << getLangOpts().CPlusPlus;
       }
-    } else
-      Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_paren;
+    } else {
+      Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+           diag::err_expected_either)
+          << tok::identifier << tok::l_paren;
+    }
     D.SetIdentifier(nullptr, Tok.getLocation());
     D.setInvalidType(true);
   }
@@ -5004,7 +5015,7 @@
 
     // An ellipsis cannot be placed outside parentheses.
     if (EllipsisLoc.isValid())
-      diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
+      DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
 
     return;
   }
@@ -5435,7 +5446,7 @@
           } else {
             // Inform the actions module about the default argument
             Actions.ActOnParamDefaultArgument(Param, EqualLoc,
-                                              DefArgResult.take());
+                                              DefArgResult.get());
           }
         }
       }
@@ -5497,7 +5508,7 @@
 
     // Remember that we parsed a array type, and remember its features.
     D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,
-                                            ExprRes.release(),
+                                            ExprRes.get(),
                                             T.getOpenLocation(),
                                             T.getCloseLocation()),
                   attrs, T.getCloseLocation());
@@ -5567,12 +5578,102 @@
   // Remember that we parsed a array type, and remember its features.
   D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
                                           StaticLoc.isValid(), isStar,
-                                          NumElements.release(),
+                                          NumElements.get(),
                                           T.getOpenLocation(),
                                           T.getCloseLocation()),
                 attrs, T.getCloseLocation());
 }
 
+/// Diagnose brackets before an identifier.
+void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
+  assert(Tok.is(tok::l_square) && "Missing opening bracket");
+  assert(!D.mayOmitIdentifier() && "Declarator cannot omit identifier");
+
+  SourceLocation StartBracketLoc = Tok.getLocation();
+  Declarator TempDeclarator(D.getDeclSpec(), D.getContext());
+
+  while (Tok.is(tok::l_square)) {
+    ParseBracketDeclarator(TempDeclarator);
+  }
+
+  // Stuff the location of the start of the brackets into the Declarator.
+  // The diagnostics from ParseDirectDeclarator will make more sense if
+  // they use this location instead.
+  if (Tok.is(tok::semi))
+    D.getName().EndLocation = StartBracketLoc;
+
+  SourceLocation SuggestParenLoc = Tok.getLocation();
+
+  // Now that the brackets are removed, try parsing the declarator again.
+  ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
+
+  // Something went wrong parsing the brackets, in which case,
+  // ParseBracketDeclarator has emitted an error, and we don't need to emit
+  // one here.
+  if (TempDeclarator.getNumTypeObjects() == 0)
+    return;
+
+  // Determine if parens will need to be suggested in the diagnostic.
+  bool NeedParens = false;
+  if (D.getNumTypeObjects() != 0) {
+    switch (D.getTypeObject(D.getNumTypeObjects() - 1).Kind) {
+    case DeclaratorChunk::Pointer:
+    case DeclaratorChunk::Reference:
+    case DeclaratorChunk::BlockPointer:
+    case DeclaratorChunk::MemberPointer:
+      NeedParens = true;
+      break;
+    case DeclaratorChunk::Array:
+    case DeclaratorChunk::Function:
+    case DeclaratorChunk::Paren:
+      break;
+    }
+  }
+
+  if (NeedParens) {
+    // Create a DeclaratorChunk for the inserted parens.
+    ParsedAttributes attrs(AttrFactory);
+    SourceLocation EndLoc = PP.getLocForEndOfToken(D.getLocEnd());
+    D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc), attrs,
+                  SourceLocation());
+  }
+
+  // Adding back the bracket info to the end of the Declarator.
+  for (unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
+    const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
+    ParsedAttributes attrs(AttrFactory);
+    attrs.set(Chunk.Common.AttrList);
+    D.AddTypeInfo(Chunk, attrs, SourceLocation());
+  }
+
+  // The missing identifier would have been diagnosed in ParseDirectDeclarator.
+  // If parentheses are required, always suggest them.
+  if (!D.getIdentifier() && !NeedParens)
+    return;
+
+  SourceLocation EndBracketLoc = TempDeclarator.getLocEnd();
+
+  // Generate the move bracket error message.
+  SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
+  SourceLocation EndLoc = PP.getLocForEndOfToken(D.getLocEnd());
+
+  if (NeedParens) {
+    Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
+        << getLangOpts().CPlusPlus
+        << FixItHint::CreateInsertion(SuggestParenLoc, "(")
+        << FixItHint::CreateInsertion(EndLoc, ")")
+        << FixItHint::CreateInsertionFromRange(
+               EndLoc, CharSourceRange(BracketRange, true))
+        << FixItHint::CreateRemoval(BracketRange);
+  } else {
+    Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
+        << getLangOpts().CPlusPlus
+        << FixItHint::CreateInsertionFromRange(
+               EndLoc, CharSourceRange(BracketRange, true))
+        << FixItHint::CreateRemoval(BracketRange);
+  }
+}
+
 /// [GNU]   typeof-specifier:
 ///           typeof ( expressions )
 ///           typeof ( type-name )
@@ -5670,7 +5771,7 @@
   const char *PrevSpec = nullptr;
   unsigned DiagID;
   if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
-                         DiagID, Result.release(),
+                         DiagID, Result.get(),
                          Actions.getASTContext().getPrintingPolicy()))
     Diag(StartLoc, DiagID) << PrevSpec;
 }
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index ddecd75..cd2e397 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -289,7 +289,7 @@
       Lang.isInvalid()
           ? nullptr
           : Actions.ActOnStartLinkageSpecification(
-                getCurScope(), DS.getSourceRange().getBegin(), Lang.take(),
+                getCurScope(), DS.getSourceRange().getBegin(), Lang.get(),
                 Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation());
 
   ParsedAttributesWithRange attrs(AttrFactory);
@@ -689,22 +689,32 @@
     return nullptr;
   }
 
-  if (ExpectAndConsume(tok::comma)) {
-    SkipUntil(tok::semi);
-    return nullptr;
-  }
+  ExprResult AssertMessage;
+  if (Tok.is(tok::r_paren)) {
+    Diag(Tok, getLangOpts().CPlusPlus1z
+                  ? diag::warn_cxx1y_compat_static_assert_no_message
+                  : diag::ext_static_assert_no_message)
+      << (getLangOpts().CPlusPlus1z
+              ? FixItHint()
+              : FixItHint::CreateInsertion(Tok.getLocation(), ", \"\""));
+  } else {
+    if (ExpectAndConsume(tok::comma)) {
+      SkipUntil(tok::semi);
+      return nullptr;
+    }
 
-  if (!isTokenStringLiteral()) {
-    Diag(Tok, diag::err_expected_string_literal)
-      << /*Source='static_assert'*/1;
-    SkipMalformedDecl();
-    return nullptr;
-  }
+    if (!isTokenStringLiteral()) {
+      Diag(Tok, diag::err_expected_string_literal)
+        << /*Source='static_assert'*/1;
+      SkipMalformedDecl();
+      return nullptr;
+    }
 
-  ExprResult AssertMessage(ParseStringLiteralExpression());
-  if (AssertMessage.isInvalid()) {
-    SkipMalformedDecl();
-    return nullptr;
+    AssertMessage = ParseStringLiteralExpression();
+    if (AssertMessage.isInvalid()) {
+      SkipMalformedDecl();
+      return nullptr;
+    }
   }
 
   T.consumeClose();
@@ -713,8 +723,8 @@
   ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
 
   return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
-                                              AssertExpr.take(),
-                                              AssertMessage.take(),
+                                              AssertExpr.get(),
+                                              AssertMessage.get(),
                                               T.getCloseLocation());
 }
 
@@ -789,7 +799,7 @@
         return EndLoc;
       }
 
-      Result = Actions.ActOnDecltypeExpression(Result.take());
+      Result = Actions.ActOnDecltypeExpression(Result.get());
     }
 
     // Match the ')'
@@ -816,7 +826,7 @@
   // Check for duplicate type specifiers (e.g. "int decltype(a)").
   if (Result.get()
         ? DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
-                             DiagID, Result.release(), Policy)
+                             DiagID, Result.get(), Policy)
         : DS.SetTypeSpecType(DeclSpec::TST_decltype_auto, StartLoc, PrevSpec,
                              DiagID, Policy)) {
     Diag(StartLoc, DiagID) << PrevSpec;
@@ -869,7 +879,7 @@
   const char *PrevSpec = nullptr;
   unsigned DiagID;
   if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec,
-                         DiagID, Result.release(),
+                         DiagID, Result.get(),
                          Actions.getASTContext().getPrintingPolicy()))
     Diag(StartLoc, DiagID) << PrevSpec;
   DS.setTypeofParensRange(T.getRange());
@@ -1939,7 +1949,7 @@
     if (AsmLabel.isInvalid())
       SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
 
-    DeclaratorInfo.setAsmLabel(AsmLabel.release());
+    DeclaratorInfo.setAsmLabel(AsmLabel.get());
     DeclaratorInfo.SetRangeEnd(Loc);
   }
 
@@ -2305,7 +2315,7 @@
       ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
                                                   DeclaratorInfo,
                                                   TemplateParams,
-                                                  BitfieldSize.release(),
+                                                  BitfieldSize.get(),
                                                   VS, HasInClassInit);
 
       if (VarTemplateDecl *VT =
@@ -2466,7 +2476,7 @@
             << 1 /* delete */;
         else
           Diag(ConsumeToken(), diag::err_deleted_non_function);
-        return ExprResult();
+        return ExprError();
       }
     } else if (Tok.is(tok::kw_default)) {
       if (IsFunction)
@@ -2474,7 +2484,7 @@
           << 0 /* default */;
       else
         Diag(ConsumeToken(), diag::err_default_special_members);
-      return ExprResult();
+      return ExprError();
     }
 
   }
@@ -2893,7 +2903,7 @@
 
     return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
                                        TemplateTypeTy, DS, IdLoc, 
-                                       InitList.take(), EllipsisLoc);
+                                       InitList.get(), EllipsisLoc);
   } else if(Tok.is(tok::l_paren)) {
     BalancedDelimiterTracker T(*this, tok::l_paren);
     T.consumeOpen();
@@ -3251,15 +3261,15 @@
       // parsing an argument list, we need to determine whether this attribute
       // was allowed to have an argument list (such as [[deprecated]]), and how
       // many arguments were parsed (so we can diagnose on [[deprecated()]]).
-      if (Attr->getMaxArgs() && !NumArgs) {

-        // The attribute was allowed to have arguments, but none were provided

-        // even though the attribute parsed successfully. This is an error.

-        // FIXME: This is a good place for a fixit which removes the parens.

-        Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;

-        return false;

-      } else if (!Attr->getMaxArgs()) {

-        // The attribute parsed successfully, but was not allowed to have any

-        // arguments. It doesn't matter whether any were provided -- the

+      if (Attr->getMaxArgs() && !NumArgs) {
+        // The attribute was allowed to have arguments, but none were provided
+        // even though the attribute parsed successfully. This is an error.
+        // FIXME: This is a good place for a fixit which removes the parens.
+        Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
+        return false;
+      } else if (!Attr->getMaxArgs()) {
+        // The attribute parsed successfully, but was not allowed to have any
+        // arguments. It doesn't matter whether any were provided -- the
         // presence of the argument list (even if empty) is diagnosed.
         Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
             << AttrName;
@@ -3390,13 +3400,23 @@
 }
 
 void Parser::DiagnoseAndSkipCXX11Attributes() {
-  if (!isCXX11AttributeSpecifier())
-    return;
-
   // Start and end location of an attribute or an attribute list.
   SourceLocation StartLoc = Tok.getLocation();
+  SourceLocation EndLoc = SkipCXX11Attributes();
+
+  if (EndLoc.isValid()) {
+    SourceRange Range(StartLoc, EndLoc);
+    Diag(StartLoc, diag::err_attributes_not_allowed)
+      << Range;
+  }
+}
+
+SourceLocation Parser::SkipCXX11Attributes() {
   SourceLocation EndLoc;
 
+  if (!isCXX11AttributeSpecifier())
+    return EndLoc;
+
   do {
     if (Tok.is(tok::l_square)) {
       BalancedDelimiterTracker T(*this, tok::l_square);
@@ -3413,11 +3433,7 @@
     }
   } while (isCXX11AttributeSpecifier());
 
-  if (EndLoc.isValid()) {
-    SourceRange Range(StartLoc, EndLoc);
-    Diag(StartLoc, diag::err_attributes_not_allowed)
-      << Range;
-  }
+  return EndLoc;
 }
 
 /// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 209b071..0c231d6 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -148,7 +148,7 @@
 
   if (!LHS.isInvalid())
     LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__,
-                               LHS.take());
+                               LHS.get());
 
   return ParseRHSOfBinaryExpression(LHS, prec::Comma);
 }
@@ -392,11 +392,11 @@
                                      Actions.getExprRange(RHS.get()).getEnd()));
 
         LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
-                                 OpToken.getKind(), LHS.take(), RHS.take());
+                                 OpToken.getKind(), LHS.get(), RHS.get());
       } else
         LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
-                                         LHS.take(), TernaryMiddle.take(),
-                                         RHS.take());
+                                         LHS.get(), TernaryMiddle.get(),
+                                         RHS.get());
     }
   }
 }
@@ -435,7 +435,8 @@
 
     if (isa<TypeDecl>(ND))
       return WantTypeSpecifiers;
-    return AllowNonTypes;
+    return AllowNonTypes &&
+           CorrectionCandidateCallback::ValidateCandidate(candidate);
   }
 
  private:
@@ -813,6 +814,7 @@
     SourceLocation TemplateKWLoc;
     CastExpressionIdValidator Validator(isTypeCast != NotTypeCast,
                                         isTypeCast != IsTypeCast);
+    Validator.IsAddressOfOperand = isAddressOfOperand;
     Name.setIdentifier(&II, ILoc);
     Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc,
                                     Name, Tok.is(tok::l_paren),
@@ -1114,7 +1116,7 @@
 
     if (!Result.isInvalid())
       Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), 
-                                         Result.take(), T.getCloseLocation());
+                                         Result.get(), T.getCloseLocation());
     return Result;
   }
 
@@ -1252,8 +1254,8 @@
       SourceLocation RLoc = Tok.getLocation();
 
       if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) {
-        LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.take(), Loc,
-                                              Idx.take(), RLoc);
+        LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc,
+                                              Idx.get(), RLoc);
       } else
         LHS = ExprError();
 
@@ -1343,7 +1345,7 @@
         assert((ArgExprs.size() == 0 || 
                 ArgExprs.size()-1 == CommaLocs.size())&&
                "Unexpected number of commas!");
-        LHS = Actions.ActOnCallExpr(getCurScope(), LHS.take(), Loc,
+        LHS = Actions.ActOnCallExpr(getCurScope(), LHS.get(), Loc,
                                     ArgExprs, Tok.getLocation(),
                                     ExecConfig);
         PT.consumeClose();
@@ -1362,7 +1364,7 @@
       ParsedType ObjectType;
       bool MayBePseudoDestructor = false;
       if (getLangOpts().CPlusPlus && !LHS.isInvalid()) {
-        Expr *Base = LHS.take();
+        Expr *Base = LHS.get();
         const Type* BaseType = Base->getType().getTypePtrOrNull();
         if (BaseType && Tok.is(tok::l_paren) &&
             (BaseType->isFunctionType() ||
@@ -1396,7 +1398,7 @@
       }
       
       if (MayBePseudoDestructor && !LHS.isInvalid()) {
-        LHS = ParseCXXPseudoDestructor(LHS.take(), OpLoc, OpKind, SS, 
+        LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, 
                                        ObjectType);
         break;
       }
@@ -1430,7 +1432,7 @@
         LHS = ExprError();
       
       if (!LHS.isInvalid())
-        LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.take(), OpLoc, 
+        LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, 
                                             OpKind, SS, TemplateKWLoc, Name,
                                  CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
                                                    : nullptr,
@@ -1441,7 +1443,7 @@
     case tok::minusminus:  // postfix-expression: postfix-expression '--'
       if (!LHS.isInvalid()) {
         LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(),
-                                          Tok.getKind(), LHS.take());
+                                          Tok.getKind(), LHS.get());
       }
       ConsumeToken();
       break;
@@ -1653,7 +1655,7 @@
     Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(),
                                                     ExprKind,
                                                     /*isType=*/false,
-                                                    Operand.release(),
+                                                    Operand.get(),
                                                     CastRange);
   return Operand;
 }
@@ -1711,7 +1713,7 @@
     if (Expr.isInvalid() || Ty.isInvalid())
       Res = ExprError();
     else
-      Res = Actions.ActOnVAArg(StartLoc, Expr.take(), Ty.get(), ConsumeParen());
+      Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen());
     break;
   }
   case tok::kw___builtin_offsetof: {
@@ -1773,7 +1775,7 @@
           SkipUntil(tok::r_paren, StopAtSemi);
           return Res;
         }
-        Comps.back().U.E = Res.release();
+        Comps.back().U.E = Res.get();
 
         ST.consumeClose();
         Comps.back().LocEnd = ST.getCloseLocation();
@@ -1824,8 +1826,8 @@
       Diag(Tok, diag::err_expected) << tok::r_paren;
       return ExprError();
     }
-    Res = Actions.ActOnChooseExpr(StartLoc, Cond.take(), Expr1.take(),
-                                  Expr2.take(), ConsumeParen());
+    Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(),
+                                  Expr2.get(), ConsumeParen());
     break;
   }
   case tok::kw___builtin_astype: {
@@ -1853,7 +1855,7 @@
       return ExprError();
     }
     
-    Res = Actions.ActOnAsTypeExpr(Expr.take(), DestTy.get(), StartLoc, 
+    Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, 
                                   ConsumeParen());
     break;
   }
@@ -1882,7 +1884,7 @@
       return ExprError();
     }
     
-    Res = Actions.ActOnConvertVectorExpr(Expr.take(), DestTy.get(), StartLoc, 
+    Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, 
                                          ConsumeParen());
     break;
   }
@@ -1893,7 +1895,7 @@
 
   // These can be followed by postfix-expr pieces because they are
   // primary-expressions.
-  return ParsePostfixExpressionSuffix(Res.take());
+  return ParsePostfixExpressionSuffix(Res.get());
 }
 
 /// ParseParenExpression - This parses the unit that starts with a '(' token,
@@ -1969,7 +1971,7 @@
 
     // If the substmt parsed correctly, build the AST node.
     if (!Stmt.isInvalid()) {
-      Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.take(), Tok.getLocation());
+      Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation());
     } else {
       Actions.ActOnStmtExprError();
     }
@@ -2096,7 +2098,7 @@
         if (!Result.isInvalid()) {
           Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
                                          DeclaratorInfo, CastTy, 
-                                         RParenLoc, Result.take());
+                                         RParenLoc, Result.get());
         }
         return Result;
       }
@@ -2125,7 +2127,7 @@
     // Don't build a paren expression unless we actually match a ')'.
     if (!Result.isInvalid() && Tok.is(tok::r_paren))
       Result =
-          Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.take());
+          Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get());
   }
 
   // Match the ')'.
@@ -2156,7 +2158,7 @@
     Diag(LParenLoc, diag::ext_c99_compound_literal);
   ExprResult Result = ParseInitializer();
   if (!Result.isInvalid() && Ty)
-    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.take());
+    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get());
   return Result;
 }
 
@@ -2181,7 +2183,7 @@
   } while (isTokenStringLiteral());
 
   // Pass the set of string tokens, ready for concatenation, to the actions.
-  return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size(),
+  return Actions.ActOnStringLiteral(StringToks,
                                     AllowUserDefinedLiteral ? getCurScope()
                                                             : nullptr);
 }
@@ -2250,7 +2252,7 @@
         SkipUntil(tok::r_paren, StopAtSemi);
         return ExprError();
       }
-      Ty = TR.release();
+      Ty = TR.get();
     }
     Types.push_back(Ty);
 
@@ -2266,7 +2268,7 @@
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
-    Exprs.push_back(ER.release());
+    Exprs.push_back(ER.get());
   } while (TryConsumeToken(tok::comma));
 
   T.consumeClose();
@@ -2275,7 +2277,7 @@
 
   return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, 
                                            T.getCloseLocation(),
-                                           ControllingExpr.release(),
+                                           ControllingExpr.get(),
                                            Types, Exprs);
 }
 
@@ -2329,7 +2331,7 @@
     if (Expr.isInvalid())
       return true;
 
-    Exprs.push_back(Expr.release());
+    Exprs.push_back(Expr.get());
 
     if (Tok.isNot(tok::comma))
       return false;
@@ -2354,7 +2356,7 @@
     if (Expr.isInvalid())
       return true;
 
-    Exprs.push_back(Expr.release());
+    Exprs.push_back(Expr.get());
 
     if (Tok.isNot(tok::comma))
       return false;
@@ -2496,7 +2498,7 @@
   StmtResult Stmt(ParseCompoundStatementBody());
   BlockScope.Exit();
   if (!Stmt.isInvalid())
-    Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.take(), getCurScope());
+    Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope());
   else
     Actions.ActOnBlockError(CaretLoc, getCurScope());
   return Result;
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index ff19826..3d1925c 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1184,7 +1184,7 @@
   BodyScope.Exit();
 
   if (!Stmt.isInvalid())
-    return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.take(), getCurScope());
+    return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get(), getCurScope());
  
   Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
   return ExprError();
@@ -1253,7 +1253,7 @@
     Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
                                        LAngleBracketLoc, DeclaratorInfo,
                                        RAngleBracketLoc,
-                                       T.getOpenLocation(), Result.take(), 
+                                       T.getOpenLocation(), Result.get(), 
                                        T.getCloseLocation());
 
   return Result;
@@ -1319,7 +1319,7 @@
         return ExprError();
 
       Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
-                                      Result.release(), RParenLoc);
+                                      Result.get(), RParenLoc);
     }
   }
 
@@ -1367,7 +1367,7 @@
 
       Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(),
                                       /*isType=*/false,
-                                      Result.release(), T.getCloseLocation());
+                                      Result.get(), T.getCloseLocation());
     }
   }
 
@@ -1494,7 +1494,7 @@
   default:
     ExprResult Expr(ParseAssignmentExpression());
     if (Expr.isInvalid()) return Expr;
-    return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.take());
+    return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.get());
   }
 }
 
@@ -1534,7 +1534,7 @@
     ExprResult Init = ParseBraceInitializer();
     if (Init.isInvalid())
       return Init;
-    Expr *InitList = Init.take();
+    Expr *InitList = Init.get();
     return Actions.ActOnCXXTypeConstructExpr(TypeRep, SourceLocation(),
                                              MultiExprArg(&InitList, 1),
                                              SourceLocation());
@@ -1636,7 +1636,7 @@
       SkipUntil(tok::semi, StopAtSemi);
       return true;
     }
-    DeclaratorInfo.setAsmLabel(AsmLabel.release());
+    DeclaratorInfo.setAsmLabel(AsmLabel.get());
     DeclaratorInfo.SetRangeEnd(Loc);
   }
 
@@ -1676,7 +1676,7 @@
   }
 
   if (!InitExpr.isInvalid())
-    Actions.AddInitializerToDecl(DeclOut, InitExpr.take(), !CopyInitialization,
+    Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization,
                                  DS.containsPlaceholderType());
   else
     Actions.ActOnInitializerError(DeclOut);
@@ -2195,7 +2195,7 @@
       TokLocs.push_back(ConsumeStringToken());
     }
 
-    StringLiteralParser Literal(Toks.data(), Toks.size(), PP);
+    StringLiteralParser Literal(Toks, PP);
     if (Literal.hadError)
       return true;
 
@@ -2617,7 +2617,7 @@
 
   return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
                              PlacementArgs, PlacementRParen,
-                             TypeIdParens, DeclaratorInfo, Initializer.take());
+                             TypeIdParens, DeclaratorInfo, Initializer.get());
 }
 
 /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
@@ -2655,7 +2655,7 @@
 
     D.AddTypeInfo(DeclaratorChunk::getArray(0,
                                             /*static=*/false, /*star=*/false,
-                                            Size.release(),
+                                            Size.get(),
                                             T.getOpenLocation(),
                                             T.getCloseLocation()),
                   Attrs, T.getCloseLocation());
@@ -2732,7 +2732,7 @@
   if (Operand.isInvalid())
     return Operand;
 
-  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take());
+  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.get());
 }
 
 static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
@@ -3017,7 +3017,7 @@
     if (!Result.isInvalid())
       Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(),
                                     DeclaratorInfo, CastTy,
-                                    Tracker.getCloseLocation(), Result.take());
+                                    Tracker.getCloseLocation(), Result.get());
     return Result;
   }
 
@@ -3028,7 +3028,7 @@
   Result = ParseExpression();
   if (!Result.isInvalid() && Tok.is(tok::r_paren))
     Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), 
-                                    Tok.getLocation(), Result.take());
+                                    Tok.getLocation(), Result.get());
 
   // Match the ')'.
   if (Result.isInvalid()) {
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index 163b35a..8536420 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -309,12 +309,12 @@
       return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                          SourceLocation(),
                                                          ParsedType(),
-                                                         Idx.take());
+                                                         Idx.get());
     }
 
     // If this is a normal array designator, remember it.
     if (Tok.isNot(tok::ellipsis)) {
-      Desig.AddDesignator(Designator::getArray(Idx.release(), StartLoc));
+      Desig.AddDesignator(Designator::getArray(Idx.get(), StartLoc));
     } else {
       // Handle the gnu array range extension.
       Diag(Tok, diag::ext_gnu_array_range);
@@ -325,8 +325,8 @@
         SkipUntil(tok::r_square, StopAtSemi);
         return RHS;
       }
-      Desig.AddDesignator(Designator::getArrayRange(Idx.release(),
-                                                    RHS.release(),
+      Desig.AddDesignator(Designator::getArrayRange(Idx.get(),
+                                                    RHS.get(),
                                                     StartLoc, EllipsisLoc));
     }
 
@@ -426,7 +426,7 @@
     
     // If we couldn't parse the subelement, bail out.
     if (!SubElt.isInvalid()) {
-      InitExprs.push_back(SubElt.release());
+      InitExprs.push_back(SubElt.get());
     } else {
       InitExprsOk = false;
 
@@ -509,7 +509,7 @@
     
     // If we couldn't parse the subelement, bail out.
     if (!SubElt.isInvalid())
-      InitExprs.push_back(SubElt.release());
+      InitExprs.push_back(SubElt.get());
     else
       InitExprsOk = false;
 
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 2878aa0..7fe72ec 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -1783,7 +1783,7 @@
   }
   // consume ';'
   ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw");
-  return Actions.ActOnObjCAtThrowStmt(atLoc, Res.take(), getCurScope());
+  return Actions.ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope());
 }
 
 /// objc-synchronized-statement:
@@ -1820,7 +1820,7 @@
 
   // Check the @synchronized operand now.
   if (!operand.isInvalid())
-    operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.take());
+    operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.get());
 
   // Parse the compound statement within a new scope.
   ParseScope bodyScope(this, Scope::DeclScope);
@@ -1911,9 +1911,9 @@
         StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
                                                               RParenLoc, 
                                                               FirstPart, 
-                                                              CatchBody.take());
+                                                              CatchBody.get());
         if (!Catch.isInvalid())
-          CatchStmts.push_back(Catch.release());
+          CatchStmts.push_back(Catch.get());
         
       } else {
         Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
@@ -1934,7 +1934,7 @@
       if (FinallyBody.isInvalid())
         FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
       FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
-                                                   FinallyBody.take());
+                                                   FinallyBody.get());
       catch_or_finally_seen = true;
       break;
     }
@@ -1944,9 +1944,9 @@
     return StmtError();
   }
   
-  return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.take(), 
+  return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(), 
                                     CatchStmts,
-                                    FinallyStmt.take());
+                                    FinallyStmt.get());
 }
 
 /// objc-autoreleasepool-statement:
@@ -1969,7 +1969,7 @@
   if (AutoreleasePoolBody.isInvalid())
     AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
   return Actions.ActOnObjCAutoreleasePoolStmt(atLoc, 
-                                                AutoreleasePoolBody.take());
+                                                AutoreleasePoolBody.get());
 }
 
 /// StashAwayMethodOrFunctionBodyTokens -  Consume the tokens and store them 
@@ -2116,12 +2116,12 @@
     }
     ConsumeToken(); // Consume the literal token.
 
-    Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.take());
+    Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.get());
     if (Lit.isInvalid())
       return Lit;
 
     return ParsePostfixExpressionSuffix(
-             Actions.BuildObjCNumericLiteral(AtLoc, Lit.take()));
+             Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()));
   }
 
   case tok::string_literal:    // primary-expression: string-literal
@@ -2222,7 +2222,7 @@
       return true;
 
     IsExpr = true;
-    TypeOrExpr = Receiver.take();
+    TypeOrExpr = Receiver.get();
     return false;
   }
 
@@ -2248,14 +2248,14 @@
     // instance method.
     ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
     if (!Receiver.isInvalid())
-      Receiver = ParsePostfixExpressionSuffix(Receiver.take());
+      Receiver = ParsePostfixExpressionSuffix(Receiver.get());
     if (!Receiver.isInvalid())
-      Receiver = ParseRHSOfBinaryExpression(Receiver.take(), prec::Comma);
+      Receiver = ParseRHSOfBinaryExpression(Receiver.get(), prec::Comma);
     if (Receiver.isInvalid())
       return true;
 
     IsExpr = true;
-    TypeOrExpr = Receiver.take();
+    TypeOrExpr = Receiver.get();
     return false;
   }
   
@@ -2401,7 +2401,7 @@
   }
 
   return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
-                                        ParsedType(), Res.take());
+                                        ParsedType(), Res.get());
 }
 
 /// \brief Parse the remainder of an Objective-C message following the
@@ -2522,7 +2522,7 @@
       }
 
       // We have a valid expression.
-      KeyExprs.push_back(Res.release());
+      KeyExprs.push_back(Res.get());
 
       // Code completion after each argument.
       if (Tok.is(tok::code_completion)) {
@@ -2566,7 +2566,7 @@
       }
 
       // We have a valid expression.
-      KeyExprs.push_back(Res.release());
+      KeyExprs.push_back(Res.get());
     }
   } else if (!selIdent) {
     Diag(Tok, diag::err_expected) << tok::identifier; // missing selector name.
@@ -2617,7 +2617,7 @@
   SmallVector<SourceLocation, 4> AtLocs;
   ExprVector AtStrings;
   AtLocs.push_back(AtLoc);
-  AtStrings.push_back(Res.release());
+  AtStrings.push_back(Res.get());
 
   while (Tok.is(tok::at)) {
     AtLocs.push_back(ConsumeToken()); // eat the @.
@@ -2630,7 +2630,7 @@
     if (Lit.isInvalid())
       return Lit;
 
-    AtStrings.push_back(Lit.release());
+    AtStrings.push_back(Lit.get());
   }
 
   return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.data(),
@@ -2657,7 +2657,7 @@
     return Lit;
   }
   ConsumeToken(); // Consume the literal token.
-  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.take());
+  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
 }
 
 /// ParseObjCNumericLiteral -
@@ -2671,7 +2671,7 @@
     return Lit;
   }
   ConsumeToken(); // Consume the literal token.
-  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.take());
+  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
 }
 
 /// ParseObjCBoxedExpr -
@@ -2694,9 +2694,9 @@
   // Wrap the sub-expression in a parenthesized expression, to distinguish
   // a boxed expression from a literal.
   SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation();
-  ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.take());
+  ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
   return Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
-                                    ValueExpr.take());
+                                    ValueExpr.get());
 }
 
 ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
@@ -2720,7 +2720,7 @@
     if (Res.isInvalid())
       return true;
 
-    ElementExprs.push_back(Res.release());
+    ElementExprs.push_back(Res.get());
 
     if (Tok.is(tok::comma))
       ConsumeToken(); // Eat the ','.
@@ -2839,7 +2839,7 @@
 }
 
 ///     objc-selector-expression
-///       @selector '(' objc-keyword-selector ')'
+///       @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
 ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
   SourceLocation SelectorLoc = ConsumeToken();
 
@@ -2851,7 +2851,10 @@
   
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
-
+  bool HasOptionalParen = Tok.is(tok::l_paren);
+  if (HasOptionalParen)
+    ConsumeParen();
+  
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
     cutOffParsing();
@@ -2864,6 +2867,7 @@
     return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
 
   KeyIdents.push_back(SelIdent);
+  
   unsigned nColons = 0;
   if (Tok.isNot(tok::r_paren)) {
     while (1) {
@@ -2891,11 +2895,14 @@
         break;
     }
   }
+  if (HasOptionalParen && Tok.is(tok::r_paren))
+    ConsumeParen(); // ')'
   T.consumeClose();
   Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
   return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
                                              T.getOpenLocation(),
-                                             T.getCloseLocation());
+                                             T.getCloseLocation(),
+                                             !HasOptionalParen);
  }
 
 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index 5916098..b3a1063 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -25,6 +25,29 @@
 // OpenMP declarative directives.
 //===----------------------------------------------------------------------===//
 
+static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
+  auto Tok = P.getCurToken();
+  auto DKind =
+      Tok.isAnnotation()
+          ? OMPD_unknown
+          : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
+  if (DKind == OMPD_parallel) {
+    Tok = P.getPreprocessor().LookAhead(0);
+    auto SDKind =
+        Tok.isAnnotation()
+            ? OMPD_unknown
+            : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
+    if (SDKind == OMPD_for) {
+      P.ConsumeToken();
+      DKind = OMPD_parallel_for;
+    } else if (SDKind == OMPD_sections) {
+      P.ConsumeToken();
+      DKind = OMPD_parallel_sections;
+    }
+  }
+  return DKind;
+}
+
 /// \brief Parsing of declarative OpenMP directives.
 ///
 ///       threadprivate-directive:
@@ -36,9 +59,7 @@
 
   SourceLocation Loc = ConsumeToken();
   SmallVector<Expr *, 5> Identifiers;
-  OpenMPDirectiveKind DKind = Tok.isAnnotation() ?
-                                  OMPD_unknown :
-                                  getOpenMPDirectiveKind(PP.getSpelling(Tok));
+  auto DKind = ParseOpenMPDirectiveKind(*this);
 
   switch (DKind) {
   case OMPD_threadprivate:
@@ -48,13 +69,12 @@
       // extra tokens.
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-          << getOpenMPDirectiveName(OMPD_threadprivate);
+            << getOpenMPDirectiveName(OMPD_threadprivate);
         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
       }
       // Skip the last annot_pragma_openmp_end.
       ConsumeToken();
-      return Actions.ActOnOpenMPThreadprivateDirective(Loc,
-                                                       Identifiers);
+      return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
     }
     break;
   case OMPD_unknown:
@@ -63,8 +83,14 @@
   case OMPD_parallel:
   case OMPD_simd:
   case OMPD_task:
+  case OMPD_for:
+  case OMPD_sections:
+  case OMPD_section:
+  case OMPD_single:
+  case OMPD_parallel_for:
+  case OMPD_parallel_sections:
     Diag(Tok, diag::err_omp_unexpected_directive)
-      << getOpenMPDirectiveName(DKind);
+        << getOpenMPDirectiveName(DKind);
     break;
   }
   SkipUntil(tok::annot_pragma_openmp_end);
@@ -77,8 +103,10 @@
 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
 ///         annot_pragma_openmp_end
 ///
-///       parallel-directive:
-///         annot_pragma_openmp 'parallel' {clause} annot_pragma_openmp_end
+///       executable-directive:
+///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
+///         'section' | 'single' | 'parallel for' | 'parallel sections' {clause}
+///         annot_pragma_openmp_end
 ///
 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
@@ -86,13 +114,11 @@
   SmallVector<Expr *, 5> Identifiers;
   SmallVector<OMPClause *, 5> Clauses;
   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
-                                               FirstClauses(OMPC_unknown + 1);
-  const unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
-                              Scope::OpenMPDirectiveScope;
+  FirstClauses(OMPC_unknown + 1);
+  unsigned ScopeFlags =
+      Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
   SourceLocation Loc = ConsumeToken(), EndLoc;
-  OpenMPDirectiveKind DKind = Tok.isAnnotation() ?
-                                  OMPD_unknown :
-                                  getOpenMPDirectiveKind(PP.getSpelling(Tok));
+  auto DKind = ParseOpenMPDirectiveKind(*this);
   // Name of critical directive.
   DeclarationNameInfo DirName;
   StmtResult Directive = StmtError();
@@ -105,28 +131,38 @@
       // extra tokens.
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-          << getOpenMPDirectiveName(OMPD_threadprivate);
+            << getOpenMPDirectiveName(OMPD_threadprivate);
         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
       }
       DeclGroupPtrTy Res =
-        Actions.ActOnOpenMPThreadprivateDirective(Loc,
-                                                  Identifiers);
+          Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
     }
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
   case OMPD_parallel:
-  case OMPD_simd: {
+  case OMPD_simd:
+  case OMPD_for:
+  case OMPD_sections:
+  case OMPD_single:
+  case OMPD_section:
+  case OMPD_parallel_for:
+  case OMPD_parallel_sections: {
     ConsumeToken();
 
-    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope());
+    if (isOpenMPLoopDirective(DKind))
+      ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
+    if (isOpenMPSimdDirective(DKind))
+      ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
+    ParseScope OMPDirectiveScope(this, ScopeFlags);
+    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
 
     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
-      OpenMPClauseKind CKind = Tok.isAnnotation() ?
-                                  OMPC_unknown :
-                                  getOpenMPClauseKind(PP.getSpelling(Tok));
-      OMPClause *Clause = ParseOpenMPClause(DKind, CKind,
-                                            !FirstClauses[CKind].getInt());
+      OpenMPClauseKind CKind = Tok.isAnnotation()
+                                   ? OMPC_unknown
+                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
+      OMPClause *Clause =
+          ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
       FirstClauses[CKind].setInt(true);
       if (Clause) {
         FirstClauses[CKind].setPointer(Clause);
@@ -144,11 +180,10 @@
 
     StmtResult AssociatedStmt;
     bool CreateDirective = true;
-    ParseScope OMPDirectiveScope(this, ScopeFlags);
     {
       // The body is a block scope like in Lambdas and Blocks.
       Sema::CompoundScopeRAII CompoundScope(Actions);
-      Actions.ActOnOpenMPRegionStart(DKind, Loc, getCurScope());
+      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
       Actions.ActOnStartOfCompoundStmt();
       // Parse statement
       AssociatedStmt = ParseStatement();
@@ -157,27 +192,26 @@
         Actions.ActOnCapturedRegionError();
         CreateDirective = false;
       } else {
-        AssociatedStmt = Actions.ActOnCapturedRegionEnd(AssociatedStmt.take());
+        AssociatedStmt = Actions.ActOnCapturedRegionEnd(AssociatedStmt.get());
         CreateDirective = AssociatedStmt.isUsable();
       }
     }
     if (CreateDirective)
-      Directive = Actions.ActOnOpenMPExecutableDirective(DKind, Clauses,
-                                                         AssociatedStmt.take(),
-                                                         Loc, EndLoc);
+      Directive = Actions.ActOnOpenMPExecutableDirective(
+          DKind, Clauses, AssociatedStmt.get(), Loc, EndLoc);
 
     // Exit scope.
     Actions.EndOpenMPDSABlock(Directive.get());
     OMPDirectiveScope.Exit();
-    }
     break;
+  }
   case OMPD_unknown:
     Diag(Tok, diag::err_omp_unknown_directive);
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
   case OMPD_task:
     Diag(Tok, diag::err_omp_unexpected_directive)
-      << getOpenMPDirectiveName(DKind);
+        << getOpenMPDirectiveName(DKind);
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
   }
@@ -231,10 +265,10 @@
           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
     } else {
       DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
-      ExprResult Res = Actions.ActOnOpenMPIdExpression(getCurScope(), SS,
-                                                       NameInfo);
+      ExprResult Res =
+          Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
       if (Res.isUsable())
-        VarList.push_back(Res.take());
+        VarList.push_back(Res.get());
     }
     // Consume ','.
     if (Tok.is(tok::comma)) {
@@ -258,7 +292,9 @@
 ///    clause:
 ///       if-clause | num_threads-clause | safelen-clause | default-clause |
 ///       private-clause | firstprivate-clause | shared-clause | linear-clause |
-///       collapse-clause
+///       aligned-clause | collapse-clause | lastprivate-clause |
+///       reduction-clause | proc_bind-clause | schedule-clause |
+///       copyin-clause | copyprivate-clause
 ///
 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
                                      OpenMPClauseKind CKind, bool FirstClause) {
@@ -266,8 +302,8 @@
   bool ErrorFound = false;
   // Check if clause is allowed for the given directive.
   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
-    Diag(Tok, diag::err_omp_unexpected_clause)
-      << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
+    Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
+                                               << getOpenMPDirectiveName(DKind);
     ErrorFound = true;
   }
 
@@ -283,8 +319,8 @@
     //  Only one safelen  clause can appear on a simd directive.
     //  Only one collapse clause can appear on a simd directive.
     if (!FirstClause) {
-      Diag(Tok, diag::err_omp_more_one_clause)
-           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind);
+      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
+                                               << getOpenMPClauseName(CKind);
     }
 
     Clause = ParseOpenMPSingleExprClause(CKind);
@@ -297,27 +333,54 @@
     // OpenMP [2.5, parallel Construct, Restrictions]
     //  At most one proc_bind clause can appear on the directive.
     if (!FirstClause) {
-      Diag(Tok, diag::err_omp_more_one_clause)
-           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind);
+      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
+                                               << getOpenMPClauseName(CKind);
     }
 
     Clause = ParseOpenMPSimpleClause(CKind);
     break;
+  case OMPC_schedule:
+    // OpenMP [2.7.1, Restrictions, p. 3]
+    //  Only one schedule clause can appear on a loop directive.
+    if (!FirstClause) {
+      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
+                                               << getOpenMPClauseName(CKind);
+    }
+
+    Clause = ParseOpenMPSingleExprWithArgClause(CKind);
+    break;
+  case OMPC_ordered:
+  case OMPC_nowait:
+    // OpenMP [2.7.1, Restrictions, p. 9]
+    //  Only one ordered clause can appear on a loop directive.
+    // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
+    //  Only one nowait clause can appear on a for directive.
+    if (!FirstClause) {
+      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
+                                               << getOpenMPClauseName(CKind);
+    }
+
+    Clause = ParseOpenMPClause(CKind);
+    break;
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
+  case OMPC_reduction:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
+  case OMPC_copyprivate:
     Clause = ParseOpenMPVarListClause(CKind);
     break;
   case OMPC_unknown:
     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-      << getOpenMPDirectiveName(DKind);
+        << getOpenMPDirectiveName(DKind);
     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
     break;
   case OMPC_threadprivate:
-    Diag(Tok, diag::err_omp_unexpected_clause)
-      << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
+    Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
+                                               << getOpenMPDirectiveName(DKind);
     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
     break;
   }
@@ -357,9 +420,8 @@
   if (Val.isInvalid())
     return nullptr;
 
-  return Actions.ActOnOpenMPSingleExprClause(Kind, Val.take(), Loc,
-                                             T.getOpenLocation(),
-                                             T.getCloseLocation());
+  return Actions.ActOnOpenMPSingleExprClause(
+      Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
 }
 
 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
@@ -379,9 +441,8 @@
                          getOpenMPClauseName(Kind)))
     return nullptr;
 
-  unsigned Type =
-      getOpenMPSimpleClauseType(Kind,
-                                Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
+  unsigned Type = getOpenMPSimpleClauseType(
+      Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
   SourceLocation TypeLoc = Tok.getLocation();
   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
       Tok.isNot(tok::annot_pragma_openmp_end))
@@ -394,38 +455,171 @@
                                          Tok.getLocation());
 }
 
-/// \brief Parsing of OpenMP clause 'private', 'firstprivate',
-/// 'shared', 'copyin', or 'reduction'.
+/// \brief Parsing of OpenMP clauses like 'ordered'.
 ///
-///    private-clause:
-///       'private' '(' list ')'
-///    firstprivate-clause:
-///       'firstprivate' '(' list ')'
-///    shared-clause:
-///       'shared' '(' list ')'
-///    linear-clause:
-///       'linear' '(' list [ ':' linear-step ] ')'
+///    ordered-clause:
+///         'ordered'
 ///
-OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
+///    nowait-clause:
+///         'nowait'
+///
+OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
   SourceLocation Loc = Tok.getLocation();
-  SourceLocation LOpen = ConsumeToken();
-  SourceLocation ColonLoc = SourceLocation();
+  ConsumeAnyToken();
+
+  return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
+}
+
+
+/// \brief Parsing of OpenMP clauses with single expressions and some additional
+/// argument like 'schedule' or 'dist_schedule'.
+///
+///    schedule-clause:
+///      'schedule' '(' kind [',' expression ] ')'
+///
+OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
+  SourceLocation Loc = ConsumeToken();
+  SourceLocation CommaLoc;
   // Parse '('.
   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   if (T.expectAndConsume(diag::err_expected_lparen_after,
                          getOpenMPClauseName(Kind)))
     return nullptr;
 
+  ExprResult Val;
+  unsigned Type = getOpenMPSimpleClauseType(
+      Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
+  SourceLocation KLoc = Tok.getLocation();
+  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
+      Tok.isNot(tok::annot_pragma_openmp_end))
+    ConsumeAnyToken();
+
+  if (Kind == OMPC_schedule &&
+      (Type == OMPC_SCHEDULE_static || Type == OMPC_SCHEDULE_dynamic ||
+       Type == OMPC_SCHEDULE_guided) &&
+      Tok.is(tok::comma)) {
+    CommaLoc = ConsumeAnyToken();
+    ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
+    Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+    if (Val.isInvalid())
+      return nullptr;
+  }
+
+  // Parse ')'.
+  T.consumeClose();
+
+  return Actions.ActOnOpenMPSingleExprWithArgClause(
+      Kind, Type, Val.get(), Loc, T.getOpenLocation(), KLoc, CommaLoc,
+      T.getCloseLocation());
+}
+
+static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
+                             UnqualifiedId &ReductionId) {
+  SourceLocation TemplateKWLoc;
+  if (ReductionIdScopeSpec.isEmpty()) {
+    auto OOK = OO_None;
+    switch (P.getCurToken().getKind()) {
+    case tok::plus:
+      OOK = OO_Plus;
+      break;
+    case tok::minus:
+      OOK = OO_Minus;
+      break;
+    case tok::star:
+      OOK = OO_Star;
+      break;
+    case tok::amp:
+      OOK = OO_Amp;
+      break;
+    case tok::pipe:
+      OOK = OO_Pipe;
+      break;
+    case tok::caret:
+      OOK = OO_Caret;
+      break;
+    case tok::ampamp:
+      OOK = OO_AmpAmp;
+      break;
+    case tok::pipepipe:
+      OOK = OO_PipePipe;
+      break;
+    default:
+      break;
+    }
+    if (OOK != OO_None) {
+      SourceLocation OpLoc = P.ConsumeToken();
+      SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
+      ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
+      return false;
+    }
+  }
+  return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
+                              /*AllowDestructorName*/ false,
+                              /*AllowConstructorName*/ false, ParsedType(),
+                              TemplateKWLoc, ReductionId);
+}
+
+/// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
+/// 'shared', 'copyin', or 'reduction'.
+///
+///    private-clause:
+///       'private' '(' list ')'
+///    firstprivate-clause:
+///       'firstprivate' '(' list ')'
+///    lastprivate-clause:
+///       'lastprivate' '(' list ')'
+///    shared-clause:
+///       'shared' '(' list ')'
+///    linear-clause:
+///       'linear' '(' list [ ':' linear-step ] ')'
+///    aligned-clause:
+///       'aligned' '(' list [ ':' alignment ] ')'
+///    reduction-clause:
+///       'reduction' '(' reduction-identifier ':' list ')'
+///
+OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
+  SourceLocation Loc = Tok.getLocation();
+  SourceLocation LOpen = ConsumeToken();
+  SourceLocation ColonLoc = SourceLocation();
+  // Optional scope specifier and unqualified id for reduction identifier.
+  CXXScopeSpec ReductionIdScopeSpec;
+  UnqualifiedId ReductionId;
+  bool InvalidReductionId = false;
+  // Parse '('.
+  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+  if (T.expectAndConsume(diag::err_expected_lparen_after,
+                         getOpenMPClauseName(Kind)))
+    return nullptr;
+
+  // Handle reduction-identifier for reduction clause.
+  if (Kind == OMPC_reduction) {
+    ColonProtectionRAIIObject ColonRAII(*this);
+    if (getLangOpts().CPlusPlus) {
+      ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, ParsedType(), false);
+    }
+    InvalidReductionId =
+        ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
+    if (InvalidReductionId) {
+      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
+                StopBeforeMatch);
+    }
+    if (Tok.is(tok::colon)) {
+      ColonLoc = ConsumeToken();
+    } else {
+      Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
+    }
+  }
+
   SmallVector<Expr *, 5> Vars;
-  bool IsComma = true;
-  const bool MayHaveTail = (Kind == OMPC_linear);
+  bool IsComma = !InvalidReductionId;
+  const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
                      Tok.isNot(tok::annot_pragma_openmp_end))) {
     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
     // Parse variable
     ExprResult VarExpr = ParseAssignmentExpression();
     if (VarExpr.isUsable()) {
-      Vars.push_back(VarExpr.take());
+      Vars.push_back(VarExpr.get());
     } else {
       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
                 StopBeforeMatch);
@@ -440,7 +634,7 @@
       Diag(Tok, diag::err_omp_expected_punc) << getOpenMPClauseName(Kind);
   }
 
-  // Parse ':' linear-step
+  // Parse ':' linear-step (or ':' alignment).
   Expr *TailExpr = nullptr;
   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
   if (MustHaveTail) {
@@ -448,7 +642,7 @@
     ConsumeToken();
     ExprResult Tail = ParseAssignmentExpression();
     if (Tail.isUsable())
-      TailExpr = Tail.take();
+      TailExpr = Tail.get();
     else
       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
                 StopBeforeMatch);
@@ -456,10 +650,13 @@
 
   // Parse ')'.
   T.consumeClose();
-  if (Vars.empty() || (MustHaveTail && !TailExpr))
+  if (Vars.empty() || (MustHaveTail && !TailExpr) || InvalidReductionId)
     return nullptr;
 
-  return Actions.ActOnOpenMPVarListClause(Kind, Vars, TailExpr, Loc, LOpen,
-                                          ColonLoc, Tok.getLocation());
+  return Actions.ActOnOpenMPVarListClause(
+      Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
+      ReductionIdScopeSpec,
+      ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
+                            : DeclarationNameInfo());
 }
 
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 787d3f0..2b248cc 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -15,6 +15,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/Scope.h"
 #include "llvm/ADT/StringSwitch.h"
 using namespace clang;
@@ -141,6 +142,12 @@
   Sema &Actions;
 };
 
+struct PragmaLoopHintHandler : public PragmaHandler {
+  PragmaLoopHintHandler() : PragmaHandler("loop") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
 }  // end namespace
 
 void Parser::initializePragmaHandlers() {
@@ -208,6 +215,9 @@
 
   OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
   PP.AddPragmaHandler("clang", OptimizeHandler.get());
+
+  LoopHintHandler.reset(new PragmaLoopHintHandler());
+  PP.AddPragmaHandler("clang", LoopHintHandler.get());
 }
 
 void Parser::resetPragmaHandlers() {
@@ -265,6 +275,9 @@
 
   PP.RemovePragmaHandler("clang", OptimizeHandler.get());
   OptimizeHandler.reset();
+
+  PP.RemovePragmaHandler("clang", LoopHintHandler.get());
+  LoopHintHandler.reset();
 }
 
 /// \brief Handle the annotation token produced for #pragma unused(...)
@@ -586,6 +599,40 @@
       DiagnosticsEngine::Error, "'#pragma %0' not implemented.");
 }
 
+struct PragmaLoopHintInfo {
+  Token Loop;
+  Token Value;
+  Token Option;
+};
+
+LoopHint Parser::HandlePragmaLoopHint() {
+  assert(Tok.is(tok::annot_pragma_loop_hint));
+  PragmaLoopHintInfo *Info =
+      static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
+
+  LoopHint Hint;
+  Hint.LoopLoc =
+      IdentifierLoc::create(Actions.Context, Info->Loop.getLocation(),
+                            Info->Loop.getIdentifierInfo());
+  Hint.OptionLoc =
+      IdentifierLoc::create(Actions.Context, Info->Option.getLocation(),
+                            Info->Option.getIdentifierInfo());
+  Hint.ValueLoc =
+      IdentifierLoc::create(Actions.Context, Info->Value.getLocation(),
+                            Info->Value.getIdentifierInfo());
+  Hint.Range =
+      SourceRange(Info->Option.getLocation(), Info->Value.getLocation());
+
+  // FIXME: We should allow non-type template parameters for the loop hint
+  // value. See bug report #19610
+  if (Info->Value.is(tok::numeric_constant))
+    Hint.ValueExpr = Actions.ActOnNumericConstant(Info->Value).get();
+  else
+    Hint.ValueExpr = nullptr;
+
+  return Hint;
+}
+
 // #pragma GCC visibility comes in two variants:
 //   'push' '(' [visibility] ')'
 //   'pop'
@@ -1164,13 +1211,11 @@
 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
                                     PragmaIntroducerKind Introducer,
                                     Token &FirstTok) {
-  if (PP.getDiagnostics().getDiagnosticLevel(diag::warn_pragma_omp_ignored,
-                                             FirstTok.getLocation()) !=
-      DiagnosticsEngine::Ignored) {
+  if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
+                                     FirstTok.getLocation())) {
     PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
-    PP.getDiagnostics().setDiagnosticMapping(diag::warn_pragma_omp_ignored,
-                                             diag::MAP_IGNORE,
-                                             SourceLocation());
+    PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
+                                    diag::Severity::Ignored, SourceLocation());
   }
   PP.DiscardUntilEndOfDirective();
 }
@@ -1584,3 +1629,129 @@
 
   Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
 }
+
+/// \brief Handle the \#pragma clang loop directive.
+///  #pragma clang 'loop' loop-hints
+///
+///  loop-hints:
+///    loop-hint loop-hints[opt]
+///
+///  loop-hint:
+///    'vectorize' '(' loop-hint-keyword ')'
+///    'interleave' '(' loop-hint-keyword ')'
+///    'unroll' '(' loop-hint-keyword ')'
+///    'vectorize_width' '(' loop-hint-value ')'
+///    'interleave_count' '(' loop-hint-value ')'
+///    'unroll_count' '(' loop-hint-value ')'
+///
+///  loop-hint-keyword:
+///    'enable'
+///    'disable'
+///
+///  loop-hint-value:
+///    constant-expression
+///
+/// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
+/// try vectorizing the instructions of the loop it precedes. Specifying
+/// interleave(enable) or interleave_count(_value_) instructs llvm to try
+/// interleaving multiple iterations of the loop it precedes. The width of the
+/// vector instructions is specified by vectorize_width() and the number of
+/// interleaved loop iterations is specified by interleave_count(). Specifying a
+/// value of 1 effectively disables vectorization/interleaving, even if it is
+/// possible and profitable, and 0 is invalid. The loop vectorizer currently
+/// only works on inner loops.
+///
+/// The unroll and unroll_count directives control the concatenation
+/// unroller. Specifying unroll(enable) instructs llvm to try to
+/// unroll the loop completely, and unroll(disable) disables unrolling
+/// for the loop. Specifying unroll_count(_value_) instructs llvm to
+/// try to unroll the loop the number of times indicated by the value.
+/// If unroll(enable) and unroll_count are both specified only
+/// unroll_count takes effect.
+void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
+                                         PragmaIntroducerKind Introducer,
+                                         Token &Tok) {
+  Token Loop = Tok;
+  SmallVector<Token, 1> TokenList;
+
+  // Lex the optimization option and verify it is an identifier.
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
+        << /*MissingOption=*/true << "";
+    return;
+  }
+
+  while (Tok.is(tok::identifier)) {
+    Token Option = Tok;
+    IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
+
+    bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
+        .Case("vectorize", true)
+        .Case("interleave", true)
+        .Case("unroll", true)
+        .Case("vectorize_width", true)
+        .Case("interleave_count", true)
+        .Case("unroll_count", true)
+        .Default(false);
+    if (!OptionValid) {
+      PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
+          << /*MissingOption=*/false << OptionInfo;
+      return;
+    }
+
+    // Read '('
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::l_paren)) {
+      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
+      return;
+    }
+
+    // FIXME: All tokens between '(' and ')' should be stored and parsed as a
+    // constant expression.
+    PP.Lex(Tok);
+    if (Tok.is(tok::r_paren)) {
+      // Nothing between the parentheses.
+      PP.Diag(Tok.getLocation(), diag::err_pragma_loop_missing_argument)
+          << OptionInfo;
+      return;
+    }
+    Token Value = Tok;
+
+    // Read ')'
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::r_paren)) {
+      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
+      return;
+    }
+
+    // Get next optimization option.
+    PP.Lex(Tok);
+
+    auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
+    Info->Loop = Loop;
+    Info->Option = Option;
+    Info->Value = Value;
+
+    // Generate the vectorization hint token.
+    Token LoopHintTok;
+    LoopHintTok.startToken();
+    LoopHintTok.setKind(tok::annot_pragma_loop_hint);
+    LoopHintTok.setLocation(Loop.getLocation());
+    LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
+    TokenList.push_back(LoopHintTok);
+  }
+
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+        << "clang loop";
+    return;
+  }
+
+  Token *TokenArray = new Token[TokenList.size()];
+  std::copy(TokenList.begin(), TokenList.end(), TokenArray);
+
+  PP.EnterTokenStream(TokenArray, TokenList.size(),
+                      /*DisableMacroExpansion=*/false,
+                      /*OwnsTokens=*/true);
+}
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 9d44f51..d29da83 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -15,29 +15,15 @@
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/Basic/Attributes.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/PrettyStackTrace.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/PrettyDeclStackTrace.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/TypoCorrection.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetAsmParser.h"
-#include "llvm/MC/MCTargetOptions.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -287,6 +273,14 @@
     break;
   }
 
+  case tok::kw___if_exists:
+  case tok::kw___if_not_exists:
+    ProhibitAttributes(Attrs);
+    ParseMicrosoftIfExistsStatement(Stmts);
+    // An __if_exists block is like a compound statement, but it doesn't create
+    // a new scope.
+    return StmtEmpty();
+
   case tok::kw_try:                 // C++ 15: try-block
     return ParseCXXTryBlock();
 
@@ -294,6 +288,11 @@
     ProhibitAttributes(Attrs); // TODO: is it correct?
     return ParseSEHTryBlock();
 
+  case tok::kw___leave:
+    Res = ParseSEHLeaveStatement();
+    SemiError = "__leave";
+    break;
+
   case tok::annot_pragma_vis:
     ProhibitAttributes(Attrs);
     HandlePragmaVisibility();
@@ -357,6 +356,10 @@
     ProhibitAttributes(Attrs);
     HandlePragmaMSPragma();
     return StmtEmpty();
+
+  case tok::annot_pragma_loop_hint:
+    ProhibitAttributes(Attrs);
+    return ParsePragmaLoopHint(Stmts, OnlyStatement, TrailingElseLoc, Attrs);
   }
 
   // If we reached this code, the statement must end in a semicolon.
@@ -424,7 +427,8 @@
   if(Tok.isNot(tok::l_brace))
     return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
 
-  StmtResult TryBlock(ParseCompoundStatement());
+  StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
+                      Scope::DeclScope | Scope::SEHTryScope));
   if(TryBlock.isInvalid())
     return TryBlock;
 
@@ -445,8 +449,8 @@
 
   return Actions.ActOnSEHTryBlock(false /* IsCXXTry */,
                                   TryLoc,
-                                  TryBlock.take(),
-                                  Handler.take());
+                                  TryBlock.get(),
+                                  Handler.get());
 }
 
 /// ParseSEHExceptBlock - Handle __except
@@ -488,7 +492,7 @@
   if(Block.isInvalid())
     return Block;
 
-  return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.take(), Block.take());
+  return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.get(), Block.get());
 }
 
 /// ParseSEHFinallyBlock - Handle __finally
@@ -505,7 +509,17 @@
   if(Block.isInvalid())
     return Block;
 
-  return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.take());
+  return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.get());
+}
+
+/// Handle __leave
+///
+/// seh-leave-statement:
+///   '__leave' ';'
+///
+StmtResult Parser::ParseSEHLeaveStatement() {
+  SourceLocation LeaveLoc = ConsumeToken();  // eat the '__leave'.
+  return Actions.ActOnSEHLeaveStmt(LeaveLoc, getCurScope());
 }
 
 /// ParseLabeledStatement - We have an identifier and a ':' after it.
@@ -915,7 +929,7 @@
 
     ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
     if (R.isUsable())
-      Stmts.push_back(R.release());
+      Stmts.push_back(R.get());
   }
 
   while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
@@ -924,12 +938,6 @@
       continue;
     }
 
-    if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
-        Tok.is(tok::kw___if_not_exists))) {
-      ParseMicrosoftIfExistsStatement(Stmts);
-      continue;
-    }
-
     StmtResult R;
     if (Tok.isNot(tok::kw___extension__)) {
       R = ParseStatementOrDeclaration(Stmts, false);
@@ -975,7 +983,7 @@
     }
 
     if (R.isUsable())
-      Stmts.push_back(R.release());
+      Stmts.push_back(R.get());
   }
 
   SourceLocation CloseLoc = Tok.getLocation();
@@ -1243,6 +1251,11 @@
   getCurScope()->AddFlags(Scope::BreakScope);
   ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
 
+  // We have incremented the mangling number for the SwitchScope and the
+  // InnerScope, which is one too many.
+  if (C99orCXX)
+    getCurScope()->decrementMSLocalManglingNumber();
+
   // Read the body statement.
   StmtResult Body(ParseStatement(TrailingElseLoc));
 
@@ -1393,6 +1406,25 @@
                              Cond.get(), T.getCloseLocation());
 }
 
+bool Parser::isForRangeIdentifier() {
+  assert(Tok.is(tok::identifier));
+
+  const Token &Next = NextToken();
+  if (Next.is(tok::colon))
+    return true;
+
+  if (Next.is(tok::l_square) || Next.is(tok::kw_alignas)) {
+    TentativeParsingAction PA(*this);
+    ConsumeToken();
+    SkipCXX11Attributes();
+    bool Result = Tok.is(tok::colon);
+    PA.Revert();
+    return Result;
+  }
+
+  return false;
+}
+
 /// ParseForStatement
 ///       for-statement: [C99 6.8.5.3]
 ///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
@@ -1476,6 +1508,29 @@
     ProhibitAttributes(attrs);
     // no first part, eat the ';'.
     ConsumeToken();
+  } else if (getLangOpts().CPlusPlus && Tok.is(tok::identifier) &&
+             isForRangeIdentifier()) {
+    ProhibitAttributes(attrs);
+    IdentifierInfo *Name = Tok.getIdentifierInfo();
+    SourceLocation Loc = ConsumeToken();
+    MaybeParseCXX11Attributes(attrs);
+
+    ForRangeInit.ColonLoc = ConsumeToken();
+    if (Tok.is(tok::l_brace))
+      ForRangeInit.RangeExpr = ParseBraceInitializer();
+    else
+      ForRangeInit.RangeExpr = ParseExpression();
+
+    Diag(Loc, getLangOpts().CPlusPlus1z
+                  ? diag::warn_cxx1y_compat_for_range_identifier
+                  : diag::ext_for_range_identifier)
+      << ((getLangOpts().CPlusPlus11 && !getLangOpts().CPlusPlus1z)
+              ? FixItHint::CreateInsertion(Loc, "auto &&")
+              : FixItHint());
+
+    FirstPart = Actions.ActOnCXXForRangeIdentifier(getCurScope(), Loc, Name,
+                                                   attrs, attrs.Range.getEnd());
+    ForRange = true;
   } else if (isForInitDeclaration()) {  // for (int X = 4;
     // Parse declaration, which eats the ';'.
     if (!C99orCXXorObjC)   // Use of C99-style for loops in C90 mode?
@@ -1596,7 +1651,7 @@
       ExprResult Third = ParseExpression();
       // FIXME: The C++11 standard doesn't actually say that this is a
       // discarded-value expression, but it clearly should be.
-      ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.take());
+      ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.get());
     }
   }
   // Match the ')'.
@@ -1609,7 +1664,7 @@
   StmtResult ForEachStmt;
 
   if (ForRange) {
-    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.take(),
+    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.get(),
                                                 ForRangeInit.ColonLoc,
                                                 ForRangeInit.RangeExpr.get(),
                                                 T.getCloseLocation(),
@@ -1620,8 +1675,8 @@
   // statement immediately in order to close over temporaries correctly.
   } else if (ForEach) {
     ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc,
-                                                     FirstPart.take(),
-                                                     Collection.take(),
+                                                     FirstPart.get(),
+                                                     Collection.get(),
                                                      T.getCloseLocation());
   }
 
@@ -1659,15 +1714,15 @@
     return StmtError();
 
   if (ForEach)
-   return Actions.FinishObjCForCollectionStmt(ForEachStmt.take(),
-                                              Body.take());
+   return Actions.FinishObjCForCollectionStmt(ForEachStmt.get(),
+                                              Body.get());
 
   if (ForRange)
-    return Actions.FinishCXXForRangeStmt(ForRangeStmt.take(), Body.take());
+    return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
 
-  return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.take(),
+  return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
                               SecondPart, SecondVar, ThirdPart,
-                              T.getCloseLocation(), Body.take());
+                              T.getCloseLocation(), Body.get());
 }
 
 /// ParseGotoStatement
@@ -1696,7 +1751,7 @@
       SkipUntil(tok::semi, StopBeforeMatch);
       return StmtError();
     }
-    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take());
+    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
   } else {
     Diag(Tok, diag::err_expected) << tok::identifier;
     return StmtError();
@@ -1756,719 +1811,37 @@
       return StmtError();
     }
   }
-  return Actions.ActOnReturnStmt(ReturnLoc, R.take(), getCurScope());
+  return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());
 }
 
-namespace {
-  class ClangAsmParserCallback : public llvm::MCAsmParserSemaCallback {
-    Parser &TheParser;
-    SourceLocation AsmLoc;
-    StringRef AsmString;
+StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
+                                       SourceLocation *TrailingElseLoc,
+                                       ParsedAttributesWithRange &Attrs) {
+  // Create temporary attribute list.
+  ParsedAttributesWithRange TempAttrs(AttrFactory);
 
-    /// The tokens we streamed into AsmString and handed off to MC.
-    ArrayRef<Token> AsmToks;
-
-    /// The offset of each token in AsmToks within AsmString.
-    ArrayRef<unsigned> AsmTokOffsets;
-
-  public:
-    ClangAsmParserCallback(Parser &P, SourceLocation Loc,
-                           StringRef AsmString,
-                           ArrayRef<Token> Toks,
-                           ArrayRef<unsigned> Offsets)
-      : TheParser(P), AsmLoc(Loc), AsmString(AsmString),
-        AsmToks(Toks), AsmTokOffsets(Offsets) {
-      assert(AsmToks.size() == AsmTokOffsets.size());
-    }
-
-    void *LookupInlineAsmIdentifier(StringRef &LineBuf,
-                                    InlineAsmIdentifierInfo &Info,
-                                    bool IsUnevaluatedContext) override {
-      // Collect the desired tokens.
-      SmallVector<Token, 16> LineToks;
-      const Token *FirstOrigToken = nullptr;
-      findTokensForString(LineBuf, LineToks, FirstOrigToken);
-
-      unsigned NumConsumedToks;
-      ExprResult Result =
-        TheParser.ParseMSAsmIdentifier(LineToks, NumConsumedToks, &Info,
-                                       IsUnevaluatedContext);
-
-      // If we consumed the entire line, tell MC that.
-      // Also do this if we consumed nothing as a way of reporting failure.
-      if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) {
-        // By not modifying LineBuf, we're implicitly consuming it all.
-
-      // Otherwise, consume up to the original tokens.
-      } else {
-        assert(FirstOrigToken && "not using original tokens?");
-
-        // Since we're using original tokens, apply that offset.
-        assert(FirstOrigToken[NumConsumedToks].getLocation()
-                  == LineToks[NumConsumedToks].getLocation());
-        unsigned FirstIndex = FirstOrigToken - AsmToks.begin();
-        unsigned LastIndex = FirstIndex + NumConsumedToks - 1;
-
-        // The total length we've consumed is the relative offset
-        // of the last token we consumed plus its length.
-        unsigned TotalOffset = (AsmTokOffsets[LastIndex]
-                                + AsmToks[LastIndex].getLength()
-                                - AsmTokOffsets[FirstIndex]);
-        LineBuf = LineBuf.substr(0, TotalOffset);
-      }
-
-      // Initialize the "decl" with the lookup result.
-      Info.OpDecl = static_cast<void*>(Result.take());
-      return Info.OpDecl;
-    }
-
-    bool LookupInlineAsmField(StringRef Base, StringRef Member,
-                              unsigned &Offset) override {
-      return TheParser.getActions().LookupInlineAsmField(Base, Member,
-                                                         Offset, AsmLoc);
-    }
-
-    static void DiagHandlerCallback(const llvm::SMDiagnostic &D,
-                                    void *Context) {
-      ((ClangAsmParserCallback*) Context)->handleDiagnostic(D);
-    }
-
-  private:
-    /// Collect the appropriate tokens for the given string.
-    void findTokensForString(StringRef Str, SmallVectorImpl<Token> &TempToks,
-                             const Token *&FirstOrigToken) const {
-      // For now, assert that the string we're working with is a substring
-      // of what we gave to MC.  This lets us use the original tokens.
-      assert(!std::less<const char*>()(Str.begin(), AsmString.begin()) &&
-             !std::less<const char*>()(AsmString.end(), Str.end()));
-
-      // Try to find a token whose offset matches the first token.
-      unsigned FirstCharOffset = Str.begin() - AsmString.begin();
-      const unsigned *FirstTokOffset
-        = std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(),
-                           FirstCharOffset);
-
-      // For now, assert that the start of the string exactly
-      // corresponds to the start of a token.
-      assert(*FirstTokOffset == FirstCharOffset);
-
-      // Use all the original tokens for this line.  (We assume the
-      // end of the line corresponds cleanly to a token break.)
-      unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin();
-      FirstOrigToken = &AsmToks[FirstTokIndex];
-      unsigned LastCharOffset = Str.end() - AsmString.begin();
-      for (unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) {
-        if (AsmTokOffsets[i] >= LastCharOffset) break;
-        TempToks.push_back(AsmToks[i]);
-      }
-    }
-
-    void handleDiagnostic(const llvm::SMDiagnostic &D) {
-      // Compute an offset into the inline asm buffer.
-      // FIXME: This isn't right if .macro is involved (but hopefully, no
-      // real-world code does that).
-      const llvm::SourceMgr &LSM = *D.getSourceMgr();
-      const llvm::MemoryBuffer *LBuf =
-        LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
-      unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
-
-      // Figure out which token that offset points into.
-      const unsigned *TokOffsetPtr =
-        std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset);
-      unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin();
-      unsigned TokOffset = *TokOffsetPtr;
-
-      // If we come up with an answer which seems sane, use it; otherwise,
-      // just point at the __asm keyword.
-      // FIXME: Assert the answer is sane once we handle .macro correctly.
-      SourceLocation Loc = AsmLoc;
-      if (TokIndex < AsmToks.size()) {
-        const Token &Tok = AsmToks[TokIndex];
-        Loc = Tok.getLocation();
-        Loc = Loc.getLocWithOffset(Offset - TokOffset);
-      }
-      TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing)
-        << D.getMessage();
-    }
-  };
-}
-
-/// Parse an identifier in an MS-style inline assembly block.
-///
-/// \param CastInfo - a void* so that we don't have to teach Parser.h
-///   about the actual type.
-ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
-                                        unsigned &NumLineToksConsumed,
-                                        void *CastInfo,
-                                        bool IsUnevaluatedContext) {
-  llvm::InlineAsmIdentifierInfo &Info =
-    *(llvm::InlineAsmIdentifierInfo *) CastInfo;
-
-  // Push a fake token on the end so that we don't overrun the token
-  // stream.  We use ';' because it expression-parsing should never
-  // overrun it.
-  const tok::TokenKind EndOfStream = tok::semi;
-  Token EndOfStreamTok;
-  EndOfStreamTok.startToken();
-  EndOfStreamTok.setKind(EndOfStream);
-  LineToks.push_back(EndOfStreamTok);
-
-  // Also copy the current token over.
-  LineToks.push_back(Tok);
-
-  PP.EnterTokenStream(LineToks.begin(),
-                      LineToks.size(),
-                      /*disable macros*/ true,
-                      /*owns tokens*/ false);
-
-  // Clear the current token and advance to the first token in LineToks.
-  ConsumeAnyToken();
-
-  // Parse an optional scope-specifier if we're in C++.
-  CXXScopeSpec SS;
-  if (getLangOpts().CPlusPlus) {
-    ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
-  }
-
-  // Require an identifier here.
-  SourceLocation TemplateKWLoc;
-  UnqualifiedId Id;
-  bool Invalid = ParseUnqualifiedId(SS,
-                                    /*EnteringContext=*/false,
-                                    /*AllowDestructorName=*/false,
-                                    /*AllowConstructorName=*/false,
-                                    /*ObjectType=*/ ParsedType(),
-                                    TemplateKWLoc,
-                                    Id);
-
-  // Figure out how many tokens we are into LineToks.
-  unsigned LineIndex = 0;
-  if (Tok.is(EndOfStream)) {
-    LineIndex = LineToks.size() - 2;
-  } else {
-    while (LineToks[LineIndex].getLocation() != Tok.getLocation()) {
-      LineIndex++;
-      assert(LineIndex < LineToks.size() - 2); // we added two extra tokens
-    }
-  }
-
-  // If we've run into the poison token we inserted before, or there
-  // was a parsing error, then claim the entire line.
-  if (Invalid || Tok.is(EndOfStream)) {
-    NumLineToksConsumed = LineToks.size() - 2;
-  } else {
-    // Otherwise, claim up to the start of the next token.
-    NumLineToksConsumed = LineIndex;
-  }
-
-  // Finally, restore the old parsing state by consuming all the tokens we
-  // staged before, implicitly killing off the token-lexer we pushed.
-  for (unsigned i = 0, e = LineToks.size() - LineIndex - 2; i != e; ++i) {
-    ConsumeAnyToken();
-  }
-  assert(Tok.is(EndOfStream));
-  ConsumeToken();
-
-  // Leave LineToks in its original state.
-  LineToks.pop_back();
-  LineToks.pop_back();
-
-  // Perform the lookup.
-  return Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info,
-                                           IsUnevaluatedContext);
-}
-
-/// Turn a sequence of our tokens back into a string that we can hand
-/// to the MC asm parser.
-static bool buildMSAsmString(Preprocessor &PP,
-                             SourceLocation AsmLoc,
-                             ArrayRef<Token> AsmToks,
-                             SmallVectorImpl<unsigned> &TokOffsets,
-                             SmallString<512> &Asm) {
-  assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
-
-  // Is this the start of a new assembly statement?
-  bool isNewStatement = true;
-
-  for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
-    const Token &Tok = AsmToks[i];
-
-    // Start each new statement with a newline and a tab.
-    if (!isNewStatement &&
-        (Tok.is(tok::kw_asm) || Tok.isAtStartOfLine())) {
-      Asm += "\n\t";
-      isNewStatement = true;
-    }
-
-    // Preserve the existence of leading whitespace except at the
-    // start of a statement.
-    if (!isNewStatement && Tok.hasLeadingSpace())
-      Asm += ' ';
-
-    // Remember the offset of this token.
-    TokOffsets.push_back(Asm.size());
-
-    // Don't actually write '__asm' into the assembly stream.
-    if (Tok.is(tok::kw_asm)) {
-      // Complain about __asm at the end of the stream.
-      if (i + 1 == e) {
-        PP.Diag(AsmLoc, diag::err_asm_empty);
-        return true;
-      }
-
-      continue;
-    }
-
-    // Append the spelling of the token.
-    SmallString<32> SpellingBuffer;
-    bool SpellingInvalid = false;
-    Asm += PP.getSpelling(Tok, SpellingBuffer, &SpellingInvalid);
-    assert(!SpellingInvalid && "spelling was invalid after correct parse?");
-
-    // We are no longer at the start of a statement.
-    isNewStatement = false;
-  }
-
-  // Ensure that the buffer is null-terminated.
-  Asm.push_back('\0');
-  Asm.pop_back();
-
-  assert(TokOffsets.size() == AsmToks.size());
-  return false;
-}
-
-/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
-/// this routine is called to collect the tokens for an MS asm statement.
-///
-/// [MS]  ms-asm-statement:
-///         ms-asm-block
-///         ms-asm-block ms-asm-statement
-///
-/// [MS]  ms-asm-block:
-///         '__asm' ms-asm-line '\n'
-///         '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt]
-///
-/// [MS]  ms-asm-instruction-block
-///         ms-asm-line
-///         ms-asm-line '\n' ms-asm-instruction-block
-///
-StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
-  SourceManager &SrcMgr = PP.getSourceManager();
-  SourceLocation EndLoc = AsmLoc;
-  SmallVector<Token, 4> AsmToks;
-
-  bool InBraces = false;
-  unsigned short savedBraceCount = 0;
-  bool InAsmComment = false;
-  FileID FID;
-  unsigned LineNo = 0;
-  unsigned NumTokensRead = 0;
-  SourceLocation LBraceLoc;
-
-  if (Tok.is(tok::l_brace)) {
-    // Braced inline asm: consume the opening brace.
-    InBraces = true;
-    savedBraceCount = BraceCount;
-    EndLoc = LBraceLoc = ConsumeBrace();
-    ++NumTokensRead;
-  } else {
-    // Single-line inline asm; compute which line it is on.
-    std::pair<FileID, unsigned> ExpAsmLoc =
-      SrcMgr.getDecomposedExpansionLoc(EndLoc);
-    FID = ExpAsmLoc.first;
-    LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
-  }
-
-  SourceLocation TokLoc = Tok.getLocation();
-  do {
-    // If we hit EOF, we're done, period.
-    if (isEofOrEom())
-      break;
-
-    if (!InAsmComment && Tok.is(tok::semi)) {
-      // A semicolon in an asm is the start of a comment.
-      InAsmComment = true;
-      if (InBraces) {
-        // Compute which line the comment is on.
-        std::pair<FileID, unsigned> ExpSemiLoc =
-          SrcMgr.getDecomposedExpansionLoc(TokLoc);
-        FID = ExpSemiLoc.first;
-        LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
-      }
-    } else if (!InBraces || InAsmComment) {
-      // If end-of-line is significant, check whether this token is on a
-      // new line.
-      std::pair<FileID, unsigned> ExpLoc =
-        SrcMgr.getDecomposedExpansionLoc(TokLoc);
-      if (ExpLoc.first != FID ||
-          SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
-        // If this is a single-line __asm, we're done.
-        if (!InBraces)
-          break;
-        // We're no longer in a comment.
-        InAsmComment = false;
-      } else if (!InAsmComment && Tok.is(tok::r_brace)) {
-        // Single-line asm always ends when a closing brace is seen.
-        // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
-        // does MSVC do here?
-        break;
-      }
-    }
-    if (!InAsmComment && InBraces && Tok.is(tok::r_brace) &&
-        BraceCount == (savedBraceCount + 1)) {
-      // Consume the closing brace, and finish
-      EndLoc = ConsumeBrace();
-      break;
-    }
-
-    // Consume the next token; make sure we don't modify the brace count etc.
-    // if we are in a comment.
-    EndLoc = TokLoc;
-    if (InAsmComment)
-      PP.Lex(Tok);
-    else {
-      AsmToks.push_back(Tok);
-      ConsumeAnyToken();
-    }
-    TokLoc = Tok.getLocation();
-    ++NumTokensRead;
-  } while (1);
-
-  if (InBraces && BraceCount != savedBraceCount) {
-    // __asm without closing brace (this can happen at EOF).
-    Diag(Tok, diag::err_expected) << tok::r_brace;
-    Diag(LBraceLoc, diag::note_matching) << tok::l_brace;
-    return StmtError();
-  } else if (NumTokensRead == 0) {
-    // Empty __asm.
-    Diag(Tok, diag::err_expected) << tok::l_brace;
-    return StmtError();
-  }
-
-  // Okay, prepare to use MC to parse the assembly.
-  SmallVector<StringRef, 4> ConstraintRefs;
-  SmallVector<Expr*, 4> Exprs;
-  SmallVector<StringRef, 4> ClobberRefs;
-
-  // We need an actual supported target.
-  const llvm::Triple &TheTriple = Actions.Context.getTargetInfo().getTriple();
-  llvm::Triple::ArchType ArchTy = TheTriple.getArch();
-  const std::string &TT = TheTriple.getTriple();
-  const llvm::Target *TheTarget = nullptr;
-  bool UnsupportedArch = (ArchTy != llvm::Triple::x86 &&
-                          ArchTy != llvm::Triple::x86_64);
-  if (UnsupportedArch) {
-    Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
-  } else {
-    std::string Error;
-    TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error);
-    if (!TheTarget)
-      Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error;
-  }
-
-  // If we don't support assembly, or the assembly is empty, we don't
-  // need to instantiate the AsmParser, etc.
-  if (!TheTarget || AsmToks.empty()) {
-    return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, StringRef(),
-                                  /*NumOutputs*/ 0, /*NumInputs*/ 0,
-                                  ConstraintRefs, ClobberRefs, Exprs, EndLoc);
-  }
-
-  // Expand the tokens into a string buffer.
-  SmallString<512> AsmString;
-  SmallVector<unsigned, 8> TokOffsets;
-  if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString))
-    return StmtError();
-
-  std::unique_ptr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
-  std::unique_ptr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT));
-  // Get the instruction descriptor.
-  std::unique_ptr<llvm::MCInstrInfo> MII(TheTarget->createMCInstrInfo());
-  std::unique_ptr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
-  std::unique_ptr<llvm::MCSubtargetInfo> STI(
-      TheTarget->createMCSubtargetInfo(TT, "", ""));
-
-  llvm::SourceMgr TempSrcMgr;
-  llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr);
-  llvm::MemoryBuffer *Buffer =
-    llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");
-
-  // Tell SrcMgr about this buffer, which is what the parser will pick up.
-  TempSrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());
-
-  std::unique_ptr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
-  std::unique_ptr<llvm::MCAsmParser> Parser(
-      createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI));
-
-  // FIXME: init MCOptions from sanitizer flags here.
-  llvm::MCTargetOptions MCOptions;
-  std::unique_ptr<llvm::MCTargetAsmParser> TargetParser(
-      TheTarget->createMCAsmParser(*STI, *Parser, *MII, MCOptions));
-
-  std::unique_ptr<llvm::MCInstPrinter> IP(
-      TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI));
-
-  // Change to the Intel dialect.
-  Parser->setAssemblerDialect(1);
-  Parser->setTargetParser(*TargetParser.get());
-  Parser->setParsingInlineAsm(true);
-  TargetParser->setParsingInlineAsm(true);
-
-  ClangAsmParserCallback Callback(*this, AsmLoc, AsmString,
-                                  AsmToks, TokOffsets);
-  TargetParser->setSemaCallback(&Callback);
-  TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback,
-                            &Callback);
-
-  unsigned NumOutputs;
-  unsigned NumInputs;
-  std::string AsmStringIR;
-  SmallVector<std::pair<void *, bool>, 4> OpExprs;
-  SmallVector<std::string, 4> Constraints;
-  SmallVector<std::string, 4> Clobbers;
-  if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR,
-                               NumOutputs, NumInputs, OpExprs, Constraints,
-                               Clobbers, MII.get(), IP.get(), Callback))
-    return StmtError();
-
-  // Filter out "fpsw".  Clang doesn't accept it, and it always lists flags and
-  // fpsr as clobbers.
-  auto End = std::remove(Clobbers.begin(), Clobbers.end(), "fpsw");
-  Clobbers.erase(End, Clobbers.end());
-
-  // Build the vector of clobber StringRefs.
-  unsigned NumClobbers = Clobbers.size();
-  ClobberRefs.resize(NumClobbers);
-  for (unsigned i = 0; i != NumClobbers; ++i)
-    ClobberRefs[i] = StringRef(Clobbers[i]);
-
-  // Recast the void pointers and build the vector of constraint StringRefs.
-  unsigned NumExprs = NumOutputs + NumInputs;
-  ConstraintRefs.resize(NumExprs);
-  Exprs.resize(NumExprs);
-  for (unsigned i = 0, e = NumExprs; i != e; ++i) {
-    Expr *OpExpr = static_cast<Expr *>(OpExprs[i].first);
-    if (!OpExpr)
-      return StmtError();
-
-    // Need address of variable.
-    if (OpExprs[i].second)
-      OpExpr = Actions.BuildUnaryOp(getCurScope(), AsmLoc, UO_AddrOf, OpExpr)
-        .take();
-
-    ConstraintRefs[i] = StringRef(Constraints[i]);
-    Exprs[i] = OpExpr;
-  }
-
-  // FIXME: We should be passing source locations for better diagnostics.
-  return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmStringIR,
-                                NumOutputs, NumInputs,
-                                ConstraintRefs, ClobberRefs, Exprs, EndLoc);
-}
-
-/// ParseAsmStatement - Parse a GNU extended asm statement.
-///       asm-statement:
-///         gnu-asm-statement
-///         ms-asm-statement
-///
-/// [GNU] gnu-asm-statement:
-///         'asm' type-qualifier[opt] '(' asm-argument ')' ';'
-///
-/// [GNU] asm-argument:
-///         asm-string-literal
-///         asm-string-literal ':' asm-operands[opt]
-///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
-///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
-///                 ':' asm-clobbers
-///
-/// [GNU] asm-clobbers:
-///         asm-string-literal
-///         asm-clobbers ',' asm-string-literal
-///
-StmtResult Parser::ParseAsmStatement(bool &msAsm) {
-  assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
-  SourceLocation AsmLoc = ConsumeToken();
-
-  if (getLangOpts().AsmBlocks && Tok.isNot(tok::l_paren) &&
-      !isTypeQualifier()) {
-    msAsm = true;
-    return ParseMicrosoftAsmStatement(AsmLoc);
-  }
-  DeclSpec DS(AttrFactory);
-  SourceLocation Loc = Tok.getLocation();
-  ParseTypeQualifierListOpt(DS, true, false);
-
-  // GNU asms accept, but warn, about type-qualifiers other than volatile.
-  if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
-    Diag(Loc, diag::w_asm_qualifier_ignored) << "const";
-  if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
-    Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict";
-  // FIXME: Once GCC supports _Atomic, check whether it permits it here.
-  if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
-    Diag(Loc, diag::w_asm_qualifier_ignored) << "_Atomic";
-
-  // Remember if this was a volatile asm.
-  bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
-  if (Tok.isNot(tok::l_paren)) {
-    Diag(Tok, diag::err_expected_lparen_after) << "asm";
-    SkipUntil(tok::r_paren, StopAtSemi);
-    return StmtError();
-  }
-  BalancedDelimiterTracker T(*this, tok::l_paren);
-  T.consumeOpen();
-
-  ExprResult AsmString(ParseAsmStringLiteral());
-  if (AsmString.isInvalid()) {
-    // Consume up to and including the closing paren.
-    T.skipToEnd();
-    return StmtError();
-  }
-
-  SmallVector<IdentifierInfo *, 4> Names;
-  ExprVector Constraints;
-  ExprVector Exprs;
-  ExprVector Clobbers;
-
-  if (Tok.is(tok::r_paren)) {
-    // We have a simple asm expression like 'asm("foo")'.
-    T.consumeClose();
-    return Actions.ActOnGCCAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
-                                   /*NumOutputs*/ 0, /*NumInputs*/ 0, nullptr,
-                                   Constraints, Exprs, AsmString.take(),
-                                   Clobbers, T.getCloseLocation());
-  }
-
-  // Parse Outputs, if present.
-  bool AteExtraColon = false;
-  if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
-    // In C++ mode, parse "::" like ": :".
-    AteExtraColon = Tok.is(tok::coloncolon);
+  // Get vectorize hints and consume annotated token.
+  while (Tok.is(tok::annot_pragma_loop_hint)) {
+    LoopHint Hint = HandlePragmaLoopHint();
     ConsumeToken();
 
-    if (!AteExtraColon &&
-        ParseAsmOperandsOpt(Names, Constraints, Exprs))
-      return StmtError();
+    if (!Hint.LoopLoc || !Hint.OptionLoc || !Hint.ValueLoc)
+      continue;
+
+    ArgsUnion ArgHints[] = {Hint.OptionLoc, Hint.ValueLoc,
+                            ArgsUnion(Hint.ValueExpr)};
+    TempAttrs.addNew(Hint.LoopLoc->Ident, Hint.Range, nullptr,
+                     Hint.LoopLoc->Loc, ArgHints, 3, AttributeList::AS_Pragma);
   }
 
-  unsigned NumOutputs = Names.size();
+  // Get the next statement.
+  MaybeParseCXX11Attributes(Attrs);
 
-  // Parse Inputs, if present.
-  if (AteExtraColon ||
-      Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
-    // In C++ mode, parse "::" like ": :".
-    if (AteExtraColon)
-      AteExtraColon = false;
-    else {
-      AteExtraColon = Tok.is(tok::coloncolon);
-      ConsumeToken();
-    }
+  StmtResult S = ParseStatementOrDeclarationAfterAttributes(
+      Stmts, OnlyStatement, TrailingElseLoc, Attrs);
 
-    if (!AteExtraColon &&
-        ParseAsmOperandsOpt(Names, Constraints, Exprs))
-      return StmtError();
-  }
-
-  assert(Names.size() == Constraints.size() &&
-         Constraints.size() == Exprs.size() &&
-         "Input operand size mismatch!");
-
-  unsigned NumInputs = Names.size() - NumOutputs;
-
-  // Parse the clobbers, if present.
-  if (AteExtraColon || Tok.is(tok::colon)) {
-    if (!AteExtraColon)
-      ConsumeToken();
-
-    // Parse the asm-string list for clobbers if present.
-    if (Tok.isNot(tok::r_paren)) {
-      while (1) {
-        ExprResult Clobber(ParseAsmStringLiteral());
-
-        if (Clobber.isInvalid())
-          break;
-
-        Clobbers.push_back(Clobber.release());
-
-        if (!TryConsumeToken(tok::comma))
-          break;
-      }
-    }
-  }
-
-  T.consumeClose();
-  return Actions.ActOnGCCAsmStmt(AsmLoc, false, isVolatile, NumOutputs,
-                                 NumInputs, Names.data(), Constraints, Exprs,
-                                 AsmString.take(), Clobbers,
-                                 T.getCloseLocation());
-}
-
-/// ParseAsmOperands - Parse the asm-operands production as used by
-/// asm-statement, assuming the leading ':' token was eaten.
-///
-/// [GNU] asm-operands:
-///         asm-operand
-///         asm-operands ',' asm-operand
-///
-/// [GNU] asm-operand:
-///         asm-string-literal '(' expression ')'
-///         '[' identifier ']' asm-string-literal '(' expression ')'
-///
-//
-// FIXME: Avoid unnecessary std::string trashing.
-bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
-                                 SmallVectorImpl<Expr *> &Constraints,
-                                 SmallVectorImpl<Expr *> &Exprs) {
-  // 'asm-operands' isn't present?
-  if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
-    return false;
-
-  while (1) {
-    // Read the [id] if present.
-    if (Tok.is(tok::l_square)) {
-      BalancedDelimiterTracker T(*this, tok::l_square);
-      T.consumeOpen();
-
-      if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected) << tok::identifier;
-        SkipUntil(tok::r_paren, StopAtSemi);
-        return true;
-      }
-
-      IdentifierInfo *II = Tok.getIdentifierInfo();
-      ConsumeToken();
-
-      Names.push_back(II);
-      T.consumeClose();
-    } else
-      Names.push_back(nullptr);
-
-    ExprResult Constraint(ParseAsmStringLiteral());
-    if (Constraint.isInvalid()) {
-        SkipUntil(tok::r_paren, StopAtSemi);
-        return true;
-    }
-    Constraints.push_back(Constraint.release());
-
-    if (Tok.isNot(tok::l_paren)) {
-      Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
-      SkipUntil(tok::r_paren, StopAtSemi);
-      return true;
-    }
-
-    // Read the parenthesized expression.
-    BalancedDelimiterTracker T(*this, tok::l_paren);
-    T.consumeOpen();
-    ExprResult Res(ParseExpression());
-    T.consumeClose();
-    if (Res.isInvalid()) {
-      SkipUntil(tok::r_paren, StopAtSemi);
-      return true;
-    }
-    Exprs.push_back(Res.release());
-    // Eat the comma and continue parsing if it exists.
-    if (!TryConsumeToken(tok::comma))
-      return false;
-  }
+  Attrs.takeAllFrom(TempAttrs);
+  return S;
 }
 
 Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
@@ -2496,7 +1869,7 @@
   }
 
   BodyScope.Exit();
-  return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
+  return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
 }
 
 /// ParseFunctionTryBlock - Parse a C++ function-try-block.
@@ -2533,7 +1906,7 @@
   }
 
   BodyScope.Exit();
-  return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
+  return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
 }
 
 bool Parser::trySkippingFunctionBody() {
@@ -2619,8 +1992,8 @@
 
     return Actions.ActOnSEHTryBlock(true /* IsCXXTry */,
                                     TryLoc,
-                                    TryBlock.take(),
-                                    Handler.take());
+                                    TryBlock.get(),
+                                    Handler.get());
   }
   else {
     StmtVector Handlers;
@@ -2634,14 +2007,14 @@
     while (Tok.is(tok::kw_catch)) {
       StmtResult Handler(ParseCXXCatchBlock(FnTry));
       if (!Handler.isInvalid())
-        Handlers.push_back(Handler.release());
+        Handlers.push_back(Handler.get());
     }
     // Don't bother creating the full statement if we don't have any usable
     // handlers.
     if (Handlers.empty())
       return StmtError();
 
-    return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(), Handlers);
+    return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
   }
 }
 
@@ -2701,7 +2074,7 @@
   if (Block.isInvalid())
     return Block;
 
-  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take());
+  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.get());
 }
 
 void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
@@ -2756,7 +2129,7 @@
   while (Tok.isNot(tok::r_brace)) {
     StmtResult R = ParseStatementOrDeclaration(Stmts, false);
     if (R.isUsable())
-      Stmts.push_back(R.release());
+      Stmts.push_back(R.get());
   }
   Braces.consumeClose();
 }
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp
new file mode 100644
index 0000000..de299fd
--- /dev/null
+++ b/lib/Parse/ParseStmtAsm.cpp
@@ -0,0 +1,761 @@
+//===---- ParseStmtAsm.cpp - Assembly Statement Parser --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements parsing for GCC and Microsoft inline assembly. 
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "RAIIObjectsForParser.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+using namespace clang;
+
+namespace {
+class ClangAsmParserCallback : public llvm::MCAsmParserSemaCallback {
+  Parser &TheParser;
+  SourceLocation AsmLoc;
+  StringRef AsmString;
+
+  /// The tokens we streamed into AsmString and handed off to MC.
+  ArrayRef<Token> AsmToks;
+
+  /// The offset of each token in AsmToks within AsmString.
+  ArrayRef<unsigned> AsmTokOffsets;
+
+public:
+  ClangAsmParserCallback(Parser &P, SourceLocation Loc, StringRef AsmString,
+                         ArrayRef<Token> Toks, ArrayRef<unsigned> Offsets)
+      : TheParser(P), AsmLoc(Loc), AsmString(AsmString), AsmToks(Toks),
+        AsmTokOffsets(Offsets) {
+    assert(AsmToks.size() == AsmTokOffsets.size());
+  }
+
+  void *LookupInlineAsmIdentifier(StringRef &LineBuf,
+                                  llvm::InlineAsmIdentifierInfo &Info,
+                                  bool IsUnevaluatedContext) override {
+    // Collect the desired tokens.
+    SmallVector<Token, 16> LineToks;
+    const Token *FirstOrigToken = nullptr;
+    findTokensForString(LineBuf, LineToks, FirstOrigToken);
+
+    unsigned NumConsumedToks;
+    ExprResult Result = TheParser.ParseMSAsmIdentifier(
+        LineToks, NumConsumedToks, &Info, IsUnevaluatedContext);
+
+    // If we consumed the entire line, tell MC that.
+    // Also do this if we consumed nothing as a way of reporting failure.
+    if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) {
+      // By not modifying LineBuf, we're implicitly consuming it all.
+
+      // Otherwise, consume up to the original tokens.
+    } else {
+      assert(FirstOrigToken && "not using original tokens?");
+
+      // Since we're using original tokens, apply that offset.
+      assert(FirstOrigToken[NumConsumedToks].getLocation() ==
+             LineToks[NumConsumedToks].getLocation());
+      unsigned FirstIndex = FirstOrigToken - AsmToks.begin();
+      unsigned LastIndex = FirstIndex + NumConsumedToks - 1;
+
+      // The total length we've consumed is the relative offset
+      // of the last token we consumed plus its length.
+      unsigned TotalOffset =
+          (AsmTokOffsets[LastIndex] + AsmToks[LastIndex].getLength() -
+           AsmTokOffsets[FirstIndex]);
+      LineBuf = LineBuf.substr(0, TotalOffset);
+    }
+
+    // Initialize the "decl" with the lookup result.
+    Info.OpDecl = static_cast<void *>(Result.get());
+    return Info.OpDecl;
+  }
+
+  bool LookupInlineAsmField(StringRef Base, StringRef Member,
+                            unsigned &Offset) override {
+    return TheParser.getActions().LookupInlineAsmField(Base, Member, Offset,
+                                                       AsmLoc);
+  }
+
+  static void DiagHandlerCallback(const llvm::SMDiagnostic &D, void *Context) {
+    ((ClangAsmParserCallback *)Context)->handleDiagnostic(D);
+  }
+
+private:
+  /// Collect the appropriate tokens for the given string.
+  void findTokensForString(StringRef Str, SmallVectorImpl<Token> &TempToks,
+                           const Token *&FirstOrigToken) const {
+    // For now, assert that the string we're working with is a substring
+    // of what we gave to MC.  This lets us use the original tokens.
+    assert(!std::less<const char *>()(Str.begin(), AsmString.begin()) &&
+           !std::less<const char *>()(AsmString.end(), Str.end()));
+
+    // Try to find a token whose offset matches the first token.
+    unsigned FirstCharOffset = Str.begin() - AsmString.begin();
+    const unsigned *FirstTokOffset = std::lower_bound(
+        AsmTokOffsets.begin(), AsmTokOffsets.end(), FirstCharOffset);
+
+    // For now, assert that the start of the string exactly
+    // corresponds to the start of a token.
+    assert(*FirstTokOffset == FirstCharOffset);
+
+    // Use all the original tokens for this line.  (We assume the
+    // end of the line corresponds cleanly to a token break.)
+    unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin();
+    FirstOrigToken = &AsmToks[FirstTokIndex];
+    unsigned LastCharOffset = Str.end() - AsmString.begin();
+    for (unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) {
+      if (AsmTokOffsets[i] >= LastCharOffset)
+        break;
+      TempToks.push_back(AsmToks[i]);
+    }
+  }
+
+  void handleDiagnostic(const llvm::SMDiagnostic &D) {
+    // Compute an offset into the inline asm buffer.
+    // FIXME: This isn't right if .macro is involved (but hopefully, no
+    // real-world code does that).
+    const llvm::SourceMgr &LSM = *D.getSourceMgr();
+    const llvm::MemoryBuffer *LBuf =
+        LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
+    unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
+
+    // Figure out which token that offset points into.
+    const unsigned *TokOffsetPtr =
+        std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset);
+    unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin();
+    unsigned TokOffset = *TokOffsetPtr;
+
+    // If we come up with an answer which seems sane, use it; otherwise,
+    // just point at the __asm keyword.
+    // FIXME: Assert the answer is sane once we handle .macro correctly.
+    SourceLocation Loc = AsmLoc;
+    if (TokIndex < AsmToks.size()) {
+      const Token &Tok = AsmToks[TokIndex];
+      Loc = Tok.getLocation();
+      Loc = Loc.getLocWithOffset(Offset - TokOffset);
+    }
+    TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage();
+  }
+};
+}
+
+/// Parse an identifier in an MS-style inline assembly block.
+///
+/// \param CastInfo - a void* so that we don't have to teach Parser.h
+///   about the actual type.
+ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
+                                        unsigned &NumLineToksConsumed,
+                                        void *CastInfo,
+                                        bool IsUnevaluatedContext) {
+  llvm::InlineAsmIdentifierInfo &Info =
+      *(llvm::InlineAsmIdentifierInfo *)CastInfo;
+
+  // Push a fake token on the end so that we don't overrun the token
+  // stream.  We use ';' because it expression-parsing should never
+  // overrun it.
+  const tok::TokenKind EndOfStream = tok::semi;
+  Token EndOfStreamTok;
+  EndOfStreamTok.startToken();
+  EndOfStreamTok.setKind(EndOfStream);
+  LineToks.push_back(EndOfStreamTok);
+
+  // Also copy the current token over.
+  LineToks.push_back(Tok);
+
+  PP.EnterTokenStream(LineToks.begin(), LineToks.size(),
+                      /*disable macros*/ true,
+                      /*owns tokens*/ false);
+
+  // Clear the current token and advance to the first token in LineToks.
+  ConsumeAnyToken();
+
+  // Parse an optional scope-specifier if we're in C++.
+  CXXScopeSpec SS;
+  if (getLangOpts().CPlusPlus) {
+    ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
+  }
+
+  // Require an identifier here.
+  SourceLocation TemplateKWLoc;
+  UnqualifiedId Id;
+  bool Invalid =
+      ParseUnqualifiedId(SS,
+                         /*EnteringContext=*/false,
+                         /*AllowDestructorName=*/false,
+                         /*AllowConstructorName=*/false,
+                         /*ObjectType=*/ParsedType(), TemplateKWLoc, Id);
+
+  // Figure out how many tokens we are into LineToks.
+  unsigned LineIndex = 0;
+  if (Tok.is(EndOfStream)) {
+    LineIndex = LineToks.size() - 2;
+  } else {
+    while (LineToks[LineIndex].getLocation() != Tok.getLocation()) {
+      LineIndex++;
+      assert(LineIndex < LineToks.size() - 2); // we added two extra tokens
+    }
+  }
+
+  // If we've run into the poison token we inserted before, or there
+  // was a parsing error, then claim the entire line.
+  if (Invalid || Tok.is(EndOfStream)) {
+    NumLineToksConsumed = LineToks.size() - 2;
+  } else {
+    // Otherwise, claim up to the start of the next token.
+    NumLineToksConsumed = LineIndex;
+  }
+
+  // Finally, restore the old parsing state by consuming all the tokens we
+  // staged before, implicitly killing off the token-lexer we pushed.
+  for (unsigned i = 0, e = LineToks.size() - LineIndex - 2; i != e; ++i) {
+    ConsumeAnyToken();
+  }
+  assert(Tok.is(EndOfStream));
+  ConsumeToken();
+
+  // Leave LineToks in its original state.
+  LineToks.pop_back();
+  LineToks.pop_back();
+
+  // Perform the lookup.
+  return Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info,
+                                           IsUnevaluatedContext);
+}
+
+/// Turn a sequence of our tokens back into a string that we can hand
+/// to the MC asm parser.
+static bool buildMSAsmString(Preprocessor &PP, SourceLocation AsmLoc,
+                             ArrayRef<Token> AsmToks,
+                             SmallVectorImpl<unsigned> &TokOffsets,
+                             SmallString<512> &Asm) {
+  assert(!AsmToks.empty() && "Didn't expect an empty AsmToks!");
+
+  // Is this the start of a new assembly statement?
+  bool isNewStatement = true;
+
+  for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
+    const Token &Tok = AsmToks[i];
+
+    // Start each new statement with a newline and a tab.
+    if (!isNewStatement && (Tok.is(tok::kw_asm) || Tok.isAtStartOfLine())) {
+      Asm += "\n\t";
+      isNewStatement = true;
+    }
+
+    // Preserve the existence of leading whitespace except at the
+    // start of a statement.
+    if (!isNewStatement && Tok.hasLeadingSpace())
+      Asm += ' ';
+
+    // Remember the offset of this token.
+    TokOffsets.push_back(Asm.size());
+
+    // Don't actually write '__asm' into the assembly stream.
+    if (Tok.is(tok::kw_asm)) {
+      // Complain about __asm at the end of the stream.
+      if (i + 1 == e) {
+        PP.Diag(AsmLoc, diag::err_asm_empty);
+        return true;
+      }
+
+      continue;
+    }
+
+    // Append the spelling of the token.
+    SmallString<32> SpellingBuffer;
+    bool SpellingInvalid = false;
+    Asm += PP.getSpelling(Tok, SpellingBuffer, &SpellingInvalid);
+    assert(!SpellingInvalid && "spelling was invalid after correct parse?");
+
+    // We are no longer at the start of a statement.
+    isNewStatement = false;
+  }
+
+  // Ensure that the buffer is null-terminated.
+  Asm.push_back('\0');
+  Asm.pop_back();
+
+  assert(TokOffsets.size() == AsmToks.size());
+  return false;
+}
+
+/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
+/// this routine is called to collect the tokens for an MS asm statement.
+///
+/// [MS]  ms-asm-statement:
+///         ms-asm-block
+///         ms-asm-block ms-asm-statement
+///
+/// [MS]  ms-asm-block:
+///         '__asm' ms-asm-line '\n'
+///         '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt]
+///
+/// [MS]  ms-asm-instruction-block
+///         ms-asm-line
+///         ms-asm-line '\n' ms-asm-instruction-block
+///
+StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
+  SourceManager &SrcMgr = PP.getSourceManager();
+  SourceLocation EndLoc = AsmLoc;
+  SmallVector<Token, 4> AsmToks;
+
+  unsigned BraceNesting = 0;
+  unsigned short savedBraceCount = 0;
+  bool InAsmComment = false;
+  FileID FID;
+  unsigned LineNo = 0;
+  unsigned NumTokensRead = 0;
+  SmallVector<SourceLocation, 4> LBraceLocs;
+  bool SkippedStartOfLine = false;
+
+  if (Tok.is(tok::l_brace)) {
+    // Braced inline asm: consume the opening brace.
+    BraceNesting = 1;
+    savedBraceCount = BraceCount;
+    EndLoc = ConsumeBrace();
+    LBraceLocs.push_back(EndLoc);
+    ++NumTokensRead;
+  } else {
+    // Single-line inline asm; compute which line it is on.
+    std::pair<FileID, unsigned> ExpAsmLoc =
+        SrcMgr.getDecomposedExpansionLoc(EndLoc);
+    FID = ExpAsmLoc.first;
+    LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
+    LBraceLocs.push_back(SourceLocation());
+  }
+
+  SourceLocation TokLoc = Tok.getLocation();
+  do {
+    // If we hit EOF, we're done, period.
+    if (isEofOrEom())
+      break;
+
+    if (!InAsmComment && Tok.is(tok::l_brace)) {
+      // Consume the opening brace.
+      SkippedStartOfLine = Tok.isAtStartOfLine();
+      EndLoc = ConsumeBrace();
+      BraceNesting++;
+      LBraceLocs.push_back(EndLoc);
+      TokLoc = Tok.getLocation();
+      ++NumTokensRead;
+      continue;
+    } else if (!InAsmComment && Tok.is(tok::semi)) {
+      // A semicolon in an asm is the start of a comment.
+      InAsmComment = true;
+      if (BraceNesting) {
+        // Compute which line the comment is on.
+        std::pair<FileID, unsigned> ExpSemiLoc =
+            SrcMgr.getDecomposedExpansionLoc(TokLoc);
+        FID = ExpSemiLoc.first;
+        LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
+      }
+    } else if (!BraceNesting || InAsmComment) {
+      // If end-of-line is significant, check whether this token is on a
+      // new line.
+      std::pair<FileID, unsigned> ExpLoc =
+          SrcMgr.getDecomposedExpansionLoc(TokLoc);
+      if (ExpLoc.first != FID ||
+          SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
+        // If this is a single-line __asm, we're done.
+        if (!BraceNesting)
+          break;
+        // We're no longer in a comment.
+        InAsmComment = false;
+      } else if (!InAsmComment && Tok.is(tok::r_brace)) {
+        // Single-line asm always ends when a closing brace is seen.
+        // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
+        // does MSVC do here?
+        break;
+      }
+    }
+    if (!InAsmComment && BraceNesting && Tok.is(tok::r_brace) &&
+        BraceCount == (savedBraceCount + BraceNesting)) {
+      // Consume the closing brace.
+      SkippedStartOfLine = Tok.isAtStartOfLine();
+      EndLoc = ConsumeBrace();
+      BraceNesting--;
+      // Finish if all of the opened braces in the inline asm section were consumed.
+      if (BraceNesting == 0)
+        break;
+      else {
+        LBraceLocs.pop_back();
+        TokLoc = Tok.getLocation();
+        ++NumTokensRead;
+        continue;
+      }
+    }
+
+    // Consume the next token; make sure we don't modify the brace count etc.
+    // if we are in a comment.
+    EndLoc = TokLoc;
+    if (InAsmComment)
+      PP.Lex(Tok);
+    else {
+      // Set the token as the start of line if we skipped the original start
+      // of line token in case it was a nested brace.
+      if (SkippedStartOfLine)
+        Tok.setFlag(Token::StartOfLine);
+      AsmToks.push_back(Tok);
+      ConsumeAnyToken();
+    }
+    TokLoc = Tok.getLocation();
+    ++NumTokensRead;
+    SkippedStartOfLine = false;
+  } while (1);
+
+  if (BraceNesting && BraceCount != savedBraceCount) {
+    // __asm without closing brace (this can happen at EOF).
+    for (unsigned i = 0; i < BraceNesting; ++i) {
+      Diag(Tok, diag::err_expected) << tok::r_brace;
+      Diag(LBraceLocs.back(), diag::note_matching) << tok::l_brace;
+      LBraceLocs.pop_back();
+    }
+    return StmtError();
+  } else if (NumTokensRead == 0) {
+    // Empty __asm.
+    Diag(Tok, diag::err_expected) << tok::l_brace;
+    return StmtError();
+  }
+
+  // Okay, prepare to use MC to parse the assembly.
+  SmallVector<StringRef, 4> ConstraintRefs;
+  SmallVector<Expr *, 4> Exprs;
+  SmallVector<StringRef, 4> ClobberRefs;
+
+  // We need an actual supported target.
+  const llvm::Triple &TheTriple = Actions.Context.getTargetInfo().getTriple();
+  llvm::Triple::ArchType ArchTy = TheTriple.getArch();
+  const std::string &TT = TheTriple.getTriple();
+  const llvm::Target *TheTarget = nullptr;
+  bool UnsupportedArch =
+      (ArchTy != llvm::Triple::x86 && ArchTy != llvm::Triple::x86_64);
+  if (UnsupportedArch) {
+    Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
+  } else {
+    std::string Error;
+    TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error);
+    if (!TheTarget)
+      Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error;
+  }
+
+  assert(!LBraceLocs.empty() && "Should have at least one location here");
+
+  // If we don't support assembly, or the assembly is empty, we don't
+  // need to instantiate the AsmParser, etc.
+  if (!TheTarget || AsmToks.empty()) {
+    return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, StringRef(),
+                                  /*NumOutputs*/ 0, /*NumInputs*/ 0,
+                                  ConstraintRefs, ClobberRefs, Exprs, EndLoc);
+  }
+
+  // Expand the tokens into a string buffer.
+  SmallString<512> AsmString;
+  SmallVector<unsigned, 8> TokOffsets;
+  if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString))
+    return StmtError();
+
+  std::unique_ptr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
+  std::unique_ptr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT));
+  // Get the instruction descriptor.
+  std::unique_ptr<llvm::MCInstrInfo> MII(TheTarget->createMCInstrInfo());
+  std::unique_ptr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
+  std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      TheTarget->createMCSubtargetInfo(TT, "", ""));
+
+  llvm::SourceMgr TempSrcMgr;
+  llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr);
+  llvm::MemoryBuffer *Buffer =
+      llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");
+
+  // Tell SrcMgr about this buffer, which is what the parser will pick up.
+  TempSrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());
+
+  std::unique_ptr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
+  std::unique_ptr<llvm::MCAsmParser> Parser(
+      createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI));
+
+  // FIXME: init MCOptions from sanitizer flags here.
+  llvm::MCTargetOptions MCOptions;
+  std::unique_ptr<llvm::MCTargetAsmParser> TargetParser(
+      TheTarget->createMCAsmParser(*STI, *Parser, *MII, MCOptions));
+
+  std::unique_ptr<llvm::MCInstPrinter> IP(
+      TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI));
+
+  // Change to the Intel dialect.
+  Parser->setAssemblerDialect(1);
+  Parser->setTargetParser(*TargetParser.get());
+  Parser->setParsingInlineAsm(true);
+  TargetParser->setParsingInlineAsm(true);
+
+  ClangAsmParserCallback Callback(*this, AsmLoc, AsmString, AsmToks,
+                                  TokOffsets);
+  TargetParser->setSemaCallback(&Callback);
+  TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback,
+                            &Callback);
+
+  unsigned NumOutputs;
+  unsigned NumInputs;
+  std::string AsmStringIR;
+  SmallVector<std::pair<void *, bool>, 4> OpExprs;
+  SmallVector<std::string, 4> Constraints;
+  SmallVector<std::string, 4> Clobbers;
+  if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR, NumOutputs,
+                               NumInputs, OpExprs, Constraints, Clobbers,
+                               MII.get(), IP.get(), Callback))
+    return StmtError();
+
+  // Filter out "fpsw".  Clang doesn't accept it, and it always lists flags and
+  // fpsr as clobbers.
+  auto End = std::remove(Clobbers.begin(), Clobbers.end(), "fpsw");
+  Clobbers.erase(End, Clobbers.end());
+
+  // Build the vector of clobber StringRefs.
+  ClobberRefs.insert(ClobberRefs.end(), Clobbers.begin(), Clobbers.end());
+
+  // Recast the void pointers and build the vector of constraint StringRefs.
+  unsigned NumExprs = NumOutputs + NumInputs;
+  ConstraintRefs.resize(NumExprs);
+  Exprs.resize(NumExprs);
+  for (unsigned i = 0, e = NumExprs; i != e; ++i) {
+    Expr *OpExpr = static_cast<Expr *>(OpExprs[i].first);
+    if (!OpExpr)
+      return StmtError();
+
+    // Need address of variable.
+    if (OpExprs[i].second)
+      OpExpr =
+          Actions.BuildUnaryOp(getCurScope(), AsmLoc, UO_AddrOf, OpExpr).get();
+
+    ConstraintRefs[i] = StringRef(Constraints[i]);
+    Exprs[i] = OpExpr;
+  }
+
+  // FIXME: We should be passing source locations for better diagnostics.
+  return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmStringIR,
+                                NumOutputs, NumInputs, ConstraintRefs,
+                                ClobberRefs, Exprs, EndLoc);
+}
+
+/// ParseAsmStatement - Parse a GNU extended asm statement.
+///       asm-statement:
+///         gnu-asm-statement
+///         ms-asm-statement
+///
+/// [GNU] gnu-asm-statement:
+///         'asm' type-qualifier[opt] '(' asm-argument ')' ';'
+///
+/// [GNU] asm-argument:
+///         asm-string-literal
+///         asm-string-literal ':' asm-operands[opt]
+///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+///                 ':' asm-clobbers
+///
+/// [GNU] asm-clobbers:
+///         asm-string-literal
+///         asm-clobbers ',' asm-string-literal
+///
+StmtResult Parser::ParseAsmStatement(bool &msAsm) {
+  assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
+  SourceLocation AsmLoc = ConsumeToken();
+
+  if (getLangOpts().AsmBlocks && Tok.isNot(tok::l_paren) &&
+      !isTypeQualifier()) {
+    msAsm = true;
+    return ParseMicrosoftAsmStatement(AsmLoc);
+  }
+  DeclSpec DS(AttrFactory);
+  SourceLocation Loc = Tok.getLocation();
+  ParseTypeQualifierListOpt(DS, true, false);
+
+  // GNU asms accept, but warn, about type-qualifiers other than volatile.
+  if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
+    Diag(Loc, diag::w_asm_qualifier_ignored) << "const";
+  if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
+    Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict";
+  // FIXME: Once GCC supports _Atomic, check whether it permits it here.
+  if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
+    Diag(Loc, diag::w_asm_qualifier_ignored) << "_Atomic";
+
+  // Remember if this was a volatile asm.
+  bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "asm";
+    SkipUntil(tok::r_paren, StopAtSemi);
+    return StmtError();
+  }
+  BalancedDelimiterTracker T(*this, tok::l_paren);
+  T.consumeOpen();
+
+  ExprResult AsmString(ParseAsmStringLiteral());
+  if (AsmString.isInvalid()) {
+    // Consume up to and including the closing paren.
+    T.skipToEnd();
+    return StmtError();
+  }
+
+  SmallVector<IdentifierInfo *, 4> Names;
+  ExprVector Constraints;
+  ExprVector Exprs;
+  ExprVector Clobbers;
+
+  if (Tok.is(tok::r_paren)) {
+    // We have a simple asm expression like 'asm("foo")'.
+    T.consumeClose();
+    return Actions.ActOnGCCAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
+                                   /*NumOutputs*/ 0, /*NumInputs*/ 0, nullptr,
+                                   Constraints, Exprs, AsmString.get(),
+                                   Clobbers, T.getCloseLocation());
+  }
+
+  // Parse Outputs, if present.
+  bool AteExtraColon = false;
+  if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
+    // In C++ mode, parse "::" like ": :".
+    AteExtraColon = Tok.is(tok::coloncolon);
+    ConsumeToken();
+
+    if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
+      return StmtError();
+  }
+
+  unsigned NumOutputs = Names.size();
+
+  // Parse Inputs, if present.
+  if (AteExtraColon || Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
+    // In C++ mode, parse "::" like ": :".
+    if (AteExtraColon)
+      AteExtraColon = false;
+    else {
+      AteExtraColon = Tok.is(tok::coloncolon);
+      ConsumeToken();
+    }
+
+    if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
+      return StmtError();
+  }
+
+  assert(Names.size() == Constraints.size() &&
+         Constraints.size() == Exprs.size() && "Input operand size mismatch!");
+
+  unsigned NumInputs = Names.size() - NumOutputs;
+
+  // Parse the clobbers, if present.
+  if (AteExtraColon || Tok.is(tok::colon)) {
+    if (!AteExtraColon)
+      ConsumeToken();
+
+    // Parse the asm-string list for clobbers if present.
+    if (Tok.isNot(tok::r_paren)) {
+      while (1) {
+        ExprResult Clobber(ParseAsmStringLiteral());
+
+        if (Clobber.isInvalid())
+          break;
+
+        Clobbers.push_back(Clobber.get());
+
+        if (!TryConsumeToken(tok::comma))
+          break;
+      }
+    }
+  }
+
+  T.consumeClose();
+  return Actions.ActOnGCCAsmStmt(
+      AsmLoc, false, isVolatile, NumOutputs, NumInputs, Names.data(),
+      Constraints, Exprs, AsmString.get(), Clobbers, T.getCloseLocation());
+}
+
+/// ParseAsmOperands - Parse the asm-operands production as used by
+/// asm-statement, assuming the leading ':' token was eaten.
+///
+/// [GNU] asm-operands:
+///         asm-operand
+///         asm-operands ',' asm-operand
+///
+/// [GNU] asm-operand:
+///         asm-string-literal '(' expression ')'
+///         '[' identifier ']' asm-string-literal '(' expression ')'
+///
+//
+// FIXME: Avoid unnecessary std::string trashing.
+bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
+                                 SmallVectorImpl<Expr *> &Constraints,
+                                 SmallVectorImpl<Expr *> &Exprs) {
+  // 'asm-operands' isn't present?
+  if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
+    return false;
+
+  while (1) {
+    // Read the [id] if present.
+    if (Tok.is(tok::l_square)) {
+      BalancedDelimiterTracker T(*this, tok::l_square);
+      T.consumeOpen();
+
+      if (Tok.isNot(tok::identifier)) {
+        Diag(Tok, diag::err_expected) << tok::identifier;
+        SkipUntil(tok::r_paren, StopAtSemi);
+        return true;
+      }
+
+      IdentifierInfo *II = Tok.getIdentifierInfo();
+      ConsumeToken();
+
+      Names.push_back(II);
+      T.consumeClose();
+    } else
+      Names.push_back(nullptr);
+
+    ExprResult Constraint(ParseAsmStringLiteral());
+    if (Constraint.isInvalid()) {
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return true;
+    }
+    Constraints.push_back(Constraint.get());
+
+    if (Tok.isNot(tok::l_paren)) {
+      Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return true;
+    }
+
+    // Read the parenthesized expression.
+    BalancedDelimiterTracker T(*this, tok::l_paren);
+    T.consumeOpen();
+    ExprResult Res(ParseExpression());
+    T.consumeClose();
+    if (Res.isInvalid()) {
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return true;
+    }
+    Exprs.push_back(Res.get());
+    // Eat the comma and continue parsing if it exists.
+    if (!TryConsumeToken(tok::comma))
+      return false;
+  }
+}
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index d8fbe0c..fa6401f 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -473,10 +473,8 @@
   SourceLocation KeyLoc = ConsumeToken();
 
   // Grab the ellipsis (if given).
-  bool Ellipsis = false;
   SourceLocation EllipsisLoc;
   if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {
-    Ellipsis = true;
     Diag(EllipsisLoc,
          getLangOpts().CPlusPlus11
            ? diag::warn_cxx98_compat_variadic_templates
@@ -498,6 +496,11 @@
     return nullptr;
   }
 
+  // Recover from misplaced ellipsis.
+  bool AlreadyHasEllipsis = EllipsisLoc.isValid();
+  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+    DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
+
   // Grab a default argument (if available).
   // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
   // we introduce the type parameter into the local scope.
@@ -507,19 +510,22 @@
     DefaultArg = ParseTypeName(/*Range=*/nullptr,
                                Declarator::TemplateTypeArgContext).get();
 
-  return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, Ellipsis, 
-                                    EllipsisLoc, KeyLoc, ParamName, NameLoc,
-                                    Depth, Position, EqualLoc, DefaultArg);
+  return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, EllipsisLoc,
+                                    KeyLoc, ParamName, NameLoc, Depth, Position,
+                                    EqualLoc, DefaultArg);
 }
 
 /// ParseTemplateTemplateParameter - Handle the parsing of template
 /// template parameters.
 ///
 ///       type-parameter:    [C++ temp.param]
-///         'template' '<' template-parameter-list '>' 'class' 
+///         'template' '<' template-parameter-list '>' type-parameter-key
 ///                  ...[opt] identifier[opt]
-///         'template' '<' template-parameter-list '>' 'class' identifier[opt] 
-///                  = id-expression
+///         'template' '<' template-parameter-list '>' type-parameter-key
+///                  identifier[opt] = id-expression
+///       type-parameter-key:
+///         'class'
+///         'typename'       [C++1z]
 Decl *
 Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
   assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
@@ -536,20 +542,29 @@
     }
   }
 
+  // Provide an ExtWarn if the C++1z feature of using 'typename' here is used.
   // Generate a meaningful error if the user forgot to put class before the
   // identifier, comma, or greater. Provide a fixit if the identifier, comma,
-  // or greater appear immediately or after 'typename' or 'struct'. In the
-  // latter case, replace the keyword with 'class'.
+  // or greater appear immediately or after 'struct'. In the latter case,
+  // replace the keyword with 'class'.
   if (!TryConsumeToken(tok::kw_class)) {
     bool Replace = Tok.is(tok::kw_typename) || Tok.is(tok::kw_struct);
-    const Token& Next = Replace ? NextToken() : Tok;
-    if (Next.is(tok::identifier) || Next.is(tok::comma) ||
-        Next.is(tok::greater) || Next.is(tok::greatergreater) ||
-        Next.is(tok::ellipsis))
+    const Token &Next = Tok.is(tok::kw_struct) ? NextToken() : Tok;
+    if (Tok.is(tok::kw_typename)) {
+      Diag(Tok.getLocation(),
+           getLangOpts().CPlusPlus1z
+               ? diag::warn_cxx1y_compat_template_template_param_typename
+               : diag::ext_template_template_param_typename)
+        << (!getLangOpts().CPlusPlus1z
+                ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
+                : FixItHint());
+    } else if (Next.is(tok::identifier) || Next.is(tok::comma) ||
+               Next.is(tok::greater) || Next.is(tok::greatergreater) ||
+               Next.is(tok::ellipsis)) {
       Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
         << (Replace ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
                     : FixItHint::CreateInsertion(Tok.getLocation(), "class "));
-    else
+    } else
       Diag(Tok.getLocation(), diag::err_class_on_template_template_param);
 
     if (Replace)
@@ -579,6 +594,11 @@
     return nullptr;
   }
 
+  // Recover from misplaced ellipsis.
+  bool AlreadyHasEllipsis = EllipsisLoc.isValid();
+  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+    DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
+
   TemplateParameterList *ParamList =
     Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
                                        TemplateLoc, LAngleLoc,
@@ -629,6 +649,11 @@
     return nullptr;
   }
 
+  // Recover from misplaced ellipsis.
+  SourceLocation EllipsisLoc;
+  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+    DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
+
   // If there is a default value, parse it.
   // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
   // we introduce the template parameter into the local scope.
@@ -651,7 +676,29 @@
   // Create the parameter.
   return Actions.ActOnNonTypeTemplateParameter(getCurScope(), ParamDecl, 
                                                Depth, Position, EqualLoc, 
-                                               DefaultArg.take());
+                                               DefaultArg.get());
+}
+
+void Parser::DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
+                                       SourceLocation CorrectLoc,
+                                       bool AlreadyHasEllipsis,
+                                       bool IdentifierHasName) {
+  FixItHint Insertion;
+  if (!AlreadyHasEllipsis)
+    Insertion = FixItHint::CreateInsertion(CorrectLoc, "...");
+  Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
+      << FixItHint::CreateRemoval(EllipsisLoc) << Insertion
+      << !IdentifierHasName;
+}
+
+void Parser::DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
+                                                   Declarator &D) {
+  assert(EllipsisLoc.isValid());
+  bool AlreadyHasEllipsis = D.getEllipsisLoc().isValid();
+  if (!AlreadyHasEllipsis)
+    D.setEllipsisLoc(EllipsisLoc);
+  DiagnoseMisplacedEllipsis(EllipsisLoc, D.getIdentifierLoc(),
+                            AlreadyHasEllipsis, D.hasName());
 }
 
 /// \brief Parses a '>' at the end of a template list.
@@ -704,7 +751,9 @@
 
   // This template-id is terminated by a token which starts with a '>'. Outside
   // C++11, this is now error recovery, and in C++11, this is error recovery if
-  // the token isn't '>>'.
+  // the token isn't '>>' or '>>>'.
+  // '>>>' is for CUDA, where this sequence of characters is parsed into
+  // tok::greatergreatergreater, rather than two separate tokens.
 
   RAngleLoc = Tok.getLocation();
 
@@ -734,7 +783,8 @@
     Hint2 = FixItHint::CreateInsertion(Next.getLocation(), " ");
 
   unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
-  if (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater))
+  if (getLangOpts().CPlusPlus11 &&
+      (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
     DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
   else if (Tok.is(tok::greaterequal))
     DiagId = diag::err_right_angle_bracket_equal_needs_space;
@@ -1118,7 +1168,7 @@
     return ParsedTemplateArgument();
 
   return ParsedTemplateArgument(ParsedTemplateArgument::NonType, 
-                                ExprArg.release(), Loc);
+                                ExprArg.get(), Loc);
 }
 
 /// \brief Determine whether the current tokens can only be parsed as a 
diff --git a/lib/Rewrite/Core/Rewriter.cpp b/lib/Rewrite/Core/Rewriter.cpp
index c0f87d2..eab4ccf 100644
--- a/lib/Rewrite/Core/Rewriter.cpp
+++ b/lib/Rewrite/Core/Rewriter.cpp
@@ -21,7 +21,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
@@ -332,6 +332,8 @@
 /// printer to generate the replacement code.  This returns true if the input
 /// could not be rewritten, or false if successful.
 bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) {
+  assert(From != nullptr && To != nullptr && "Expected non-null Stmt's");
+
   // Measaure the old text.
   int Size = getRangeSize(From->getSourceRange());
   if (Size == -1)
@@ -348,6 +350,7 @@
 }
 
 std::string Rewriter::ConvertToString(Stmt *From) {
+  assert(From != nullptr && "Expected non-null Stmt");
   std::string SStr;
   llvm::raw_string_ostream S(SStr);
   From->printPretty(S, nullptr, PrintingPolicy(*LangOpts));
@@ -454,8 +457,8 @@
     // Win32 does not allow rename/removing opened files.
     FileStream.reset();
 #endif
-    if (llvm::error_code ec =
-          llvm::sys::fs::rename(TempFilename.str(), Filename)) {
+    if (std::error_code ec =
+            llvm::sys::fs::rename(TempFilename.str(), Filename)) {
       AllWritten = false;
       Diagnostics.Report(clang::diag::err_unable_to_rename_temp)
         << TempFilename << Filename << ec.message();
diff --git a/lib/Rewrite/Frontend/RewriteModernObjC.cpp b/lib/Rewrite/Frontend/RewriteModernObjC.cpp
index 3cacbdd..43de31c 100644
--- a/lib/Rewrite/Frontend/RewriteModernObjC.cpp
+++ b/lib/Rewrite/Frontend/RewriteModernObjC.cpp
@@ -267,6 +267,7 @@
     }
 
     void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's");
       if (DisableReplaceStmt)
         return;
 
@@ -2587,6 +2588,7 @@
 }
 
 Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  assert (Exp != nullptr && "Expected non-null ObjCStringLiteral");
   QualType strType = getConstantStringStructType();
 
   std::string S = "__NSConstantStringImpl_";
diff --git a/lib/Rewrite/Frontend/RewriteObjC.cpp b/lib/Rewrite/Frontend/RewriteObjC.cpp
index beadb93..dfeb11a 100644
--- a/lib/Rewrite/Frontend/RewriteObjC.cpp
+++ b/lib/Rewrite/Frontend/RewriteObjC.cpp
@@ -216,6 +216,7 @@
     }
 
     void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's");
       if (DisableReplaceStmt)
         return;
 
@@ -1697,6 +1698,7 @@
                                       CK, syncExpr);
   std::string syncExprBufS;
   llvm::raw_string_ostream syncExprBuf(syncExprBufS);
+  assert(syncExpr != nullptr && "Expected non-null Expr");
   syncExpr->printPretty(syncExprBuf, nullptr, PrintingPolicy(LangOpts));
   syncBuf += syncExprBuf.str();
   syncBuf += ");";
@@ -2485,6 +2487,7 @@
 }
 
 Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  assert(Exp != nullptr && "Expected non-null ObjCStringLiteral");
   QualType strType = getConstantStringStructType();
 
   std::string S = "__NSConstantStringImpl_";
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 7f2748e..213d6fb 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -477,14 +477,13 @@
                         bool HasNoReturn) const {
     if (funMode == Function) {
       return (ReturnsVoid ||
-              D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function,
-                                   FuncLoc) == DiagnosticsEngine::Ignored)
-        && (!HasNoReturn ||
-            D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr,
-                                 FuncLoc) == DiagnosticsEngine::Ignored)
-        && (!ReturnsVoid ||
-            D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
-              == DiagnosticsEngine::Ignored);
+              D.isIgnored(diag::warn_maybe_falloff_nonvoid_function,
+                          FuncLoc)) &&
+             (!HasNoReturn ||
+              D.isIgnored(diag::warn_noreturn_function_has_return_expr,
+                          FuncLoc)) &&
+             (!ReturnsVoid ||
+              D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
     }
 
     // For blocks / lambdas.
@@ -612,8 +611,9 @@
   QualType VariableTy = VD->getType().getCanonicalType();
   if (VariableTy->isBlockPointerType() &&
       !VD->hasAttr<BlocksAttr>()) {
-    S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName()
-    << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
+    S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization)
+        << VD->getDeclName()
+        << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
     return true;
   }
 
@@ -1026,6 +1026,9 @@
     // methods separately.
     bool TraverseDecl(Decl *D) { return true; }
 
+    // We analyze lambda bodies separately. Skip them here.
+    bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
+
   private:
 
     static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
@@ -1713,8 +1716,7 @@
 }
 
 static unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) {
-  return (unsigned) D.getDiagnosticLevel(diag, SourceLocation()) !=
-                    DiagnosticsEngine::Ignored;
+  return (unsigned)!D.isIgnored(diag, SourceLocation());
 }
 
 clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
@@ -1819,8 +1821,8 @@
 
   // Install the logical handler for -Wtautological-overlap-compare
   std::unique_ptr<LogicalErrorHandler> LEH;
-  if (Diags.getDiagnosticLevel(diag::warn_tautological_overlap_comparison,
-                               D->getLocStart())) {
+  if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
+                       D->getLocStart())) {
     LEH.reset(new LogicalErrorHandler(S));
     AC.getCFGBuildOptions().Observer = LEH.get();
   }
@@ -1895,8 +1897,7 @@
     SourceLocation FL = AC.getDecl()->getLocation();
     SourceLocation FEL = AC.getDecl()->getLocEnd();
     thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL);
-    if (Diags.getDiagnosticLevel(diag::warn_thread_safety_beta,D->getLocStart())
-        != DiagnosticsEngine::Ignored)
+    if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getLocStart()))
       Reporter.setIssueBetaWarnings(true);
 
     thread_safety::runThreadSafetyAnalysis(AC, Reporter);
@@ -1910,12 +1911,9 @@
     Analyzer.run(AC);
   }
 
-  if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart())
-      != DiagnosticsEngine::Ignored ||
-      Diags.getDiagnosticLevel(diag::warn_sometimes_uninit_var,D->getLocStart())
-      != DiagnosticsEngine::Ignored ||
-      Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart())
-      != DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_uninit_var, D->getLocStart()) ||
+      !Diags.isIgnored(diag::warn_sometimes_uninit_var, D->getLocStart()) ||
+      !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getLocStart())) {
     if (CFG *cfg = AC.getCFG()) {
       UninitValsDiagReporter reporter(S);
       UninitVariablesAnalysisStats stats;
@@ -1938,25 +1936,21 @@
   }
 
   bool FallThroughDiagFull =
-      Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough,
-                               D->getLocStart()) != DiagnosticsEngine::Ignored;
-  bool FallThroughDiagPerFunction =
-      Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough_per_function,
-                               D->getLocStart()) != DiagnosticsEngine::Ignored;
+      !Diags.isIgnored(diag::warn_unannotated_fallthrough, D->getLocStart());
+  bool FallThroughDiagPerFunction = !Diags.isIgnored(
+      diag::warn_unannotated_fallthrough_per_function, D->getLocStart());
   if (FallThroughDiagFull || FallThroughDiagPerFunction) {
     DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
   }
 
   if (S.getLangOpts().ObjCARCWeak &&
-      Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                               D->getLocStart()) != DiagnosticsEngine::Ignored)
+      !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getLocStart()))
     diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
 
 
   // Check for infinite self-recursion in functions
-  if (Diags.getDiagnosticLevel(diag::warn_infinite_recursive_function,
-                               D->getLocStart())
-      != DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_infinite_recursive_function,
+                       D->getLocStart())) {
     if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
       checkRecursiveFunction(S, FD, Body, AC);
     }
@@ -1964,7 +1958,7 @@
 
   // If none of the previous checks caused a CFG build, trigger one here
   // for -Wtautological-overlap-compare
-  if (Diags.getDiagnosticLevel(diag::warn_tautological_overlap_comparison,
+  if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
                                D->getLocStart())) {
     AC.getCFG();
   }
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 69415ce..d7372b7 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -178,7 +178,7 @@
   I.Kind                        = Function;
   I.Loc                         = LocalRangeBegin;
   I.EndLoc                      = LocalRangeEnd;
-  I.Fun.AttrList                = 0;
+  I.Fun.AttrList                = nullptr;
   I.Fun.hasPrototype            = hasProto;
   I.Fun.isVariadic              = EllipsisLoc.isValid();
   I.Fun.isAmbiguous             = isAmbiguous;
@@ -188,7 +188,7 @@
   I.Fun.DeleteParams            = false;
   I.Fun.TypeQuals               = TypeQuals;
   I.Fun.NumParams               = NumParams;
-  I.Fun.Params                  = 0;
+  I.Fun.Params                  = nullptr;
   I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
   I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
   I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
@@ -197,8 +197,8 @@
   I.Fun.ExceptionSpecType       = ESpecType;
   I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
   I.Fun.NumExceptions           = 0;
-  I.Fun.Exceptions              = 0;
-  I.Fun.NoexceptExpr            = 0;
+  I.Fun.Exceptions              = nullptr;
+  I.Fun.NoexceptExpr            = nullptr;
   I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
                                   TrailingReturnType.isInvalid();
   I.Fun.TrailingReturnType      = TrailingReturnType.get();
@@ -657,7 +657,7 @@
   DeclRep = Rep;
   TSTLoc = TagKwLoc;
   TSTNameLoc = TagNameLoc;
-  TypeSpecOwned = Owned && Rep != 0;
+  TypeSpecOwned = Owned && Rep != nullptr;
   return false;
 }
 
@@ -1169,7 +1169,7 @@
 
 bool DeclSpec::isMissingDeclaratorOk() {
   TST tst = getTypeSpecType();
-  return isDeclRep(tst) && getRepAsDecl() != 0 &&
+  return isDeclRep(tst) && getRepAsDecl() != nullptr &&
     StorageClassSpec != DeclSpec::SCS_typedef;
 }
 
diff --git a/lib/Sema/DelayedDiagnostic.cpp b/lib/Sema/DelayedDiagnostic.cpp
index 13a428c..664a6b1 100644
--- a/lib/Sema/DelayedDiagnostic.cpp
+++ b/lib/Sema/DelayedDiagnostic.cpp
@@ -25,7 +25,8 @@
                                     const NamedDecl *D,
                                     const ObjCInterfaceDecl *UnknownObjCClass,
                                     const ObjCPropertyDecl  *ObjCProperty,
-                                    StringRef Msg) {
+                                    StringRef Msg,
+                                    bool ObjCPropertyAccess) {
   DelayedDiagnostic DD;
   switch (AD) {
     case Sema::AD_Deprecation:
@@ -48,6 +49,7 @@
 
   DD.DeprecationData.Message = MessageData;
   DD.DeprecationData.MessageLen = Msg.size();
+  DD.DeprecationData.ObjCPropertyAccess = ObjCPropertyAccess;
   return DD;
 }
 
diff --git a/lib/Sema/Scope.cpp b/lib/Sema/Scope.cpp
index 278b087..6c79778 100644
--- a/lib/Sema/Scope.cpp
+++ b/lib/Sema/Scope.cpp
@@ -39,6 +39,10 @@
     BlockParent    = parent->BlockParent;
     TemplateParamParent = parent->TemplateParamParent;
     MSLocalManglingParent = parent->MSLocalManglingParent;
+    if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
+                  FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
+        0)
+      Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
   } else {
     Depth = 0;
     PrototypeDepth = 0;
@@ -63,6 +67,7 @@
 
   // If this is a prototype scope, record that.
   if (flags & FunctionPrototypeScope) PrototypeDepth++;
+
   if (flags & DeclScope) {
     if (flags & FunctionPrototypeScope)
       ; // Prototype scopes are uninteresting.
@@ -70,6 +75,8 @@
       ; // Nested class scopes aren't ambiguous.
     else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
       ; // Classes inside of namespaces aren't ambiguous.
+    else if ((flags & EnumScope))
+      ; // Don't increment for enum scopes.
     else
       incrementMSLocalManglingNumber();
   }
@@ -175,9 +182,18 @@
     } else if (Flags & FnTryCatchScope) {
       OS << "FnTryCatchScope";
       Flags &= ~FnTryCatchScope;
+    } else if (Flags & SEHTryScope) {
+      OS << "SEHTryScope";
+      Flags &= ~SEHTryScope;
     } else if (Flags & OpenMPDirectiveScope) {
       OS << "OpenMPDirectiveScope";
       Flags &= ~OpenMPDirectiveScope;
+    } else if (Flags & OpenMPLoopDirectiveScope) {
+      OS << "OpenMPLoopDirectiveScope";
+      Flags &= ~OpenMPLoopDirectiveScope;
+    } else if (Flags & OpenMPSimdDirectiveScope) {
+      OS << "OpenMPSimdDirectiveScope";
+      Flags &= ~OpenMPSimdDirectiveScope;
     }
 
     if (Flags)
diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp
index d9b2ca3..4d079e7 100644
--- a/lib/Sema/ScopeInfo.cpp
+++ b/lib/Sema/ScopeInfo.cpp
@@ -158,8 +158,14 @@
 
   // Has this weak object been seen before?
   FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
-  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E))
-    Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
+  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    if (isa<OpaqueValueExpr>(RefExpr->getBase()))
+     Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
+    else {
+      markSafeWeakUse(RefExpr->getBase());
+      return;
+    }
+  }
   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
   else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index e8b487e..478c34f 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -313,7 +313,8 @@
   if (VK == VK_RValue && !E->isRValue()) {
     switch (Kind) {
     default:
-      assert(0 && "can't implicitly cast lvalue to rvalue with this cast kind");
+      llvm_unreachable("can't implicitly cast lvalue to rvalue with this cast "
+                       "kind");
     case CK_LValueToRValue:
     case CK_ArrayToPointerDecay:
     case CK_FunctionToPointerDecay:
@@ -328,7 +329,7 @@
   QualType TypeTy = Context.getCanonicalType(Ty);
 
   if (ExprTy == TypeTy)
-    return Owned(E);
+    return E;
 
   // If this is a derived-to-base cast to a through a virtual base, we
   // need a vtable.
@@ -346,11 +347,11 @@
     if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
       ImpCast->setType(Ty);
       ImpCast->setValueKind(VK);
-      return Owned(E);
+      return E;
     }
   }
 
-  return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK));
+  return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK);
 }
 
 /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
@@ -681,9 +682,7 @@
   }
 
   if (LangOpts.CPlusPlus11 &&
-      Diags.getDiagnosticLevel(diag::warn_delegating_ctor_cycle,
-                               SourceLocation())
-        != DiagnosticsEngine::Ignored)
+      !Diags.isIgnored(diag::warn_delegating_ctor_cycle, SourceLocation()))
     CheckDelegatingCtorCycles();
 
   if (TUKind == TU_Module) {
@@ -823,9 +822,7 @@
     checkUndefinedButUsed(*this);
   }
 
-  if (Diags.getDiagnosticLevel(diag::warn_unused_private_field,
-                               SourceLocation())
-        != DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_unused_private_field, SourceLocation())) {
     RecordCompleteMap RecordsComplete;
     RecordCompleteMap MNCComplete;
     for (NamedDeclSetType::iterator I = UnusedPrivateFields.begin(),
@@ -1408,7 +1405,7 @@
 
     // FIXME: Try this before emitting the fixit, and suppress diagnostics
     // while doing so.
-    E = ActOnCallExpr(nullptr, E.take(), Range.getEnd(), None,
+    E = ActOnCallExpr(nullptr, E.get(), Range.getEnd(), None,
                       Range.getEnd().getLocWithOffset(1));
     return true;
   }
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index dc574f1..ffdb0aa 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -1252,7 +1252,8 @@
     << (base->getAccessSpecifierAsWritten() == AS_none);
 
   if (entity.isMemberAccess())
-    S.Diag(entity.getTargetDecl()->getLocation(), diag::note_field_decl);
+    S.Diag(entity.getTargetDecl()->getLocation(),
+           diag::note_member_declared_at);
 }
 
 static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 8c42335..a70aca2 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -532,9 +532,7 @@
       Diag(R.getNameLoc(), diag::err_expected_class_or_namespace)
           << &Identifier << getLangOpts().CPlusPlus;
       if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
-        Diag(ND->getLocation(),
-             diag::note_expected_class_or_namespace_declared_here)
-            << &Identifier;
+        Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
       return true;
     }
   }
@@ -718,9 +716,7 @@
       Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
           << &Identifier << getLangOpts().CPlusPlus;
       if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
-        Diag(ND->getLocation(),
-             diag::note_expected_class_or_namespace_declared_here)
-          << &Identifier;
+        Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
     }
   } else if (SS.isSet())
     Diag(IdentifierLoc, diag::err_no_member) << &Identifier << LookupCtx
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index df4e823..ae5436c 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -93,7 +93,7 @@
                                             CK_Dependent, castExpr, nullptr,
                                             castExpr->getValueKind());
       }
-      return Self.Owned(castExpr);
+      return castExpr;
     }
 
     // Internal convenience methods.
@@ -134,7 +134,7 @@
       if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
         return;
 
-      SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+      SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
       if (SrcExpr.isInvalid())
         return;
       PlaceholderKind = (BuiltinType::Kind) 0;
@@ -239,7 +239,7 @@
 Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
                         TypeSourceInfo *DestTInfo, Expr *E,
                         SourceRange AngleBrackets, SourceRange Parens) {
-  ExprResult Ex = Owned(E);
+  ExprResult Ex = E;
   QualType DestType = DestTInfo->getType();
 
   // If the type is dependent, we won't do the semantic analysis now.
@@ -262,7 +262,7 @@
         return ExprError();
     }
     return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType,
-                                  Op.ValueKind, Op.SrcExpr.take(), DestTInfo,
+                                  Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
                                                 OpLoc, Parens.getEnd(),
                                                 AngleBrackets));
 
@@ -273,7 +273,7 @@
         return ExprError();
     }
     return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType,
-                                    Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+                                    Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
                                                   &Op.BasePath, DestTInfo,
                                                   OpLoc, Parens.getEnd(),
                                                   AngleBrackets));
@@ -285,7 +285,7 @@
         return ExprError();
     }
     return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType,
-                                    Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+                                    Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
                                                       nullptr, DestTInfo, OpLoc,
                                                       Parens.getEnd(),
                                                       AngleBrackets));
@@ -298,7 +298,7 @@
     }
     
     return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType,
-                                   Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+                                   Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
                                                  &Op.BasePath, DestTInfo,
                                                  OpLoc, Parens.getEnd(),
                                                  AngleBrackets));
@@ -535,9 +535,9 @@
 /// checked downcasts in class hierarchies.
 void CastOperation::CheckDynamicCast() {
   if (ValueKind == VK_RValue)
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
   else if (isPlaceholder())
-    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
     return;
 
@@ -600,6 +600,11 @@
     }
     SrcPointee = SrcType;
   } else {
+    // If we're dynamic_casting from a prvalue to an rvalue reference, we need
+    // to materialize the prvalue before we bind the reference to it.
+    if (SrcExpr.get()->isRValue())
+      SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
+          SrcType, SrcExpr.get(), /*IsLValueReference*/false);
     SrcPointee = SrcType;
   }
 
@@ -648,7 +653,7 @@
       SrcExpr = ExprError();
       return;
     }
-        
+
     Kind = CK_DerivedToBase;
 
     // If we are casting to or through a virtual base class, we need a
@@ -690,9 +695,9 @@
 /// legacy_function(const_cast\<char*\>(str));
 void CastOperation::CheckConstCast() {
   if (ValueKind == VK_RValue)
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
   else if (isPlaceholder())
-    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
     return;
 
@@ -805,7 +810,7 @@
 /// char *bytes = reinterpret_cast\<char*\>(int_ptr);
 void CastOperation::CheckReinterpretCast() {
   if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload))
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
   else
     checkNonOverloadPlaceholders();
   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
@@ -864,13 +869,13 @@
         return;
     }
 
-    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
     return;
   }
 
   if (ValueKind == VK_RValue && !DestType->isRecordType() &&
       !isPlaceholder(BuiltinType::Overload)) {
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
     if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
       return;
   }
@@ -1156,6 +1161,9 @@
 
   QualType DestPointee = DestReference->getPointeeType();
 
+  // FIXME: If the source is a prvalue, we should issue a warning (because the
+  // cast always has undefined behavior), and for AST consistency, we should
+  // materialize a temporary.
   return TryStaticDowncast(Self, 
                            Self.Context.getCanonicalType(SrcExpr->getType()), 
                            Self.Context.getCanonicalType(DestPointee), CStyle,
@@ -1589,7 +1597,7 @@
     // This is a const_cast from a class prvalue to an rvalue reference type.
     // Materialize a temporary to store the result of the conversion.
     SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
-        SrcType, SrcExpr.take(), /*IsLValueReference*/ false);
+        SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
 
   return TC_Success;
 }
@@ -1606,10 +1614,8 @@
                         diag::warn_pointer_indirection_from_incompatible_type :
                         diag::warn_undefined_reinterpret_cast;
 
-  if (Diags.getDiagnosticLevel(DiagID, Range.getBegin()) ==
-          DiagnosticsEngine::Ignored) {
+  if (Diags.isIgnored(DiagID, Range.getBegin()))
     return;
-  }
 
   QualType SrcTy, DestTy;
   if (IsDereference) {
@@ -2024,7 +2030,7 @@
         return;
     }
 
-    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
     return;
   }
 
@@ -2037,7 +2043,7 @@
 
   if (ValueKind == VK_RValue && !DestType->isRecordType() &&
       !isPlaceholder(BuiltinType::Overload)) {
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
     if (SrcExpr.isInvalid())
       return;
   }
@@ -2127,9 +2133,8 @@
 /// pointer; etc. Cast to 'void' is an exception.
 static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr,
                                   QualType DestType) {
-  if (Self.Diags.getDiagnosticLevel(diag::warn_bad_function_cast,
-                                    SrcExpr.get()->getExprLoc()) 
-        == DiagnosticsEngine::Ignored)
+  if (Self.Diags.isIgnored(diag::warn_bad_function_cast,
+                           SrcExpr.get()->getExprLoc()))
     return;
   
   if (!isa<CallExpr>(SrcExpr.get()))
@@ -2175,7 +2180,7 @@
   // type needs to be scalar.
   if (DestType->isVoidType()) {
     // We don't necessarily do lvalue-to-rvalue conversions on this.
-    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
     if (SrcExpr.isInvalid())
       return;
 
@@ -2184,7 +2189,7 @@
     return;
   }
 
-  SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+  SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
   if (SrcExpr.isInvalid())
     return;
   QualType SrcType = SrcExpr.get()->getType();
@@ -2265,7 +2270,7 @@
   }
 
   if (DestType->isExtVectorType()) {
-    SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.take(), Kind);
+    SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
     return;
   }
 
@@ -2387,7 +2392,7 @@
     return ExprError();
 
   return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType,
-                              Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+                              Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
                               &Op.BasePath, CastTypeInfo, LPLoc, RPLoc));
 }
 
@@ -2409,5 +2414,5 @@
 
   return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
                          Op.ValueKind, CastTypeInfo, Op.Kind,
-                         Op.SrcExpr.take(), &Op.BasePath, LPLoc, RPLoc));
+                         Op.SrcExpr.get(), &Op.BasePath, LPLoc, RPLoc));
 }
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 83fb1d7..f7d5623 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -101,19 +101,19 @@
   if (checkArgCount(S, TheCall, 1))
     return true;
 
-  ExprResult Arg(S.Owned(TheCall->getArg(0)));
+  ExprResult Arg(TheCall->getArg(0));
   QualType ResultType = S.CheckAddressOfOperand(Arg, TheCall->getLocStart());
   if (ResultType.isNull())
     return true;
 
-  TheCall->setArg(0, Arg.take());
+  TheCall->setArg(0, Arg.get());
   TheCall->setType(ResultType);
   return false;
 }
 
 ExprResult
 Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
-  ExprResult TheCallResult(Owned(TheCall));
+  ExprResult TheCallResult(TheCall);
 
   // Find out if any arguments are required to be integer constant expressions.
   unsigned ICEArguments = 0;
@@ -296,8 +296,22 @@
     if (SemaBuiltinAddressof(*this, TheCall))
       return ExprError();
     break;
+  case Builtin::BI__builtin_operator_new:
+  case Builtin::BI__builtin_operator_delete:
+    if (!getLangOpts().CPlusPlus) {
+      Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language)
+        << (BuiltinID == Builtin::BI__builtin_operator_new
+                ? "__builtin_operator_new"
+                : "__builtin_operator_delete")
+        << "C++";
+      return ExprError();
+    }
+    // CodeGen assumes it can find the global new and delete to call,
+    // so ensure that they are declared.
+    DeclareGlobalNewDelete();
+    break;
   }
-  
+
   // Since the target specific builtins for each arch overlap, only check those
   // of the arch we are compiling for.
   if (BuiltinID >= Builtin::FirstTSBuiltin) {
@@ -472,12 +486,18 @@
 bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
                                         unsigned MaxWidth) {
   assert((BuiltinID == ARM::BI__builtin_arm_ldrex ||
+          BuiltinID == ARM::BI__builtin_arm_ldaex ||
           BuiltinID == ARM::BI__builtin_arm_strex ||
+          BuiltinID == ARM::BI__builtin_arm_stlex ||
           BuiltinID == AArch64::BI__builtin_arm_ldrex ||
-          BuiltinID == AArch64::BI__builtin_arm_strex) &&
+          BuiltinID == AArch64::BI__builtin_arm_ldaex ||
+          BuiltinID == AArch64::BI__builtin_arm_strex ||
+          BuiltinID == AArch64::BI__builtin_arm_stlex) &&
          "unexpected ARM builtin");
   bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex ||
-                 BuiltinID == AArch64::BI__builtin_arm_ldrex;
+                 BuiltinID == ARM::BI__builtin_arm_ldaex ||
+                 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+                 BuiltinID == AArch64::BI__builtin_arm_ldaex;
 
   DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
 
@@ -493,7 +513,7 @@
   ExprResult PointerArgRes = DefaultFunctionArrayLvalueConversion(PointerArg);
   if (PointerArgRes.isInvalid())
     return true;
-  PointerArg = PointerArgRes.take();
+  PointerArg = PointerArgRes.get();
 
   const PointerType *pointerType = PointerArg->getType()->getAs<PointerType>();
   if (!pointerType) {
@@ -525,7 +545,7 @@
   PointerArgRes = ImpCastExprToType(PointerArg, AddrType, CastNeeded);
   if (PointerArgRes.isInvalid())
     return true;
-  PointerArg = PointerArgRes.take();
+  PointerArg = PointerArgRes.get();
 
   TheCall->setArg(IsLdrex ? 0 : 1, PointerArg);
 
@@ -584,15 +604,17 @@
   llvm::APSInt Result;
 
   if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
-      BuiltinID == ARM::BI__builtin_arm_strex) {
+      BuiltinID == ARM::BI__builtin_arm_ldaex ||
+      BuiltinID == ARM::BI__builtin_arm_strex ||
+      BuiltinID == ARM::BI__builtin_arm_stlex) {
     return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64);
   }
 
   if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
     return true;
 
-  // For NEON intrinsics which take an immediate value as part of the
-  // instruction, range check them here.
+  // For intrinsics which take an immediate value as part of the instruction,
+  // range check them here.
   unsigned i = 0, l = 0, u = 0;
   switch (BuiltinID) {
   default: return false;
@@ -601,7 +623,8 @@
   case ARM::BI__builtin_arm_vcvtr_f:
   case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break;
   case ARM::BI__builtin_arm_dmb:
-  case ARM::BI__builtin_arm_dsb: l = 0; u = 15; break;
+  case ARM::BI__builtin_arm_dsb:
+  case ARM::BI__builtin_arm_isb: l = 0; u = 15; break;
   }
 
   // FIXME: VFP Intrinsics should error if VFP not present.
@@ -613,7 +636,9 @@
   llvm::APSInt Result;
 
   if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
-      BuiltinID == AArch64::BI__builtin_arm_strex) {
+      BuiltinID == AArch64::BI__builtin_arm_ldaex ||
+      BuiltinID == AArch64::BI__builtin_arm_strex ||
+      BuiltinID == AArch64::BI__builtin_arm_stlex) {
     return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128);
   }
 
@@ -1219,7 +1244,7 @@
     Diag(AE->getLocStart(), diag::err_atomic_load_store_uses_lib) <<
     ((Op == AtomicExpr::AO__c11_atomic_load) ? 0 : 1);
 
-  return Owned(AE);
+  return AE;
 }
 
 
@@ -1243,7 +1268,7 @@
   if (Arg.isInvalid())
     return true;
 
-  E->setArg(ArgIndex, Arg.take());
+  E->setArg(ArgIndex, Arg.get());
   return false;
 }
 
@@ -1278,7 +1303,7 @@
   ExprResult FirstArgResult = DefaultFunctionArrayLvalueConversion(FirstArg);
   if (FirstArgResult.isInvalid())
     return ExprError();
-  FirstArg = FirstArgResult.take();
+  FirstArg = FirstArgResult.get();
   TheCall->setArg(0, FirstArg);
 
   const PointerType *pointerType = FirstArg->getType()->getAs<PointerType>();
@@ -1556,7 +1581,7 @@
     // pass in 42.  The 42 gets converted to char.  This is even more strange
     // for things like 45.123 -> char, etc.
     // FIXME: Do this check.
-    TheCall->setArg(i+1, Arg.take());
+    TheCall->setArg(i+1, Arg.get());
   }
 
   ASTContext& Context = this->getASTContext();
@@ -1577,7 +1602,7 @@
   QualType CalleePtrTy = Context.getPointerType(NewBuiltinDecl->getType());
   ExprResult PromotedCall = ImpCastExprToType(NewDRE, CalleePtrTy,
                                               CK_BuiltinFnToFnPtr);
-  TheCall->setCallee(PromotedCall.take());
+  TheCall->setCallee(PromotedCall.get());
 
   // Change the result type of the call to match the original value type. This
   // is arbitrary, but the codegen for these builtins ins design to handle it
@@ -1861,9 +1886,9 @@
     TheCall->setArg(i, nullptr);
   }
 
-  return Owned(new (Context) ShuffleVectorExpr(Context, exprs, resType,
-                                            TheCall->getCallee()->getLocStart(),
-                                            TheCall->getRParenLoc()));
+  return new (Context) ShuffleVectorExpr(Context, exprs, resType,
+                                         TheCall->getCallee()->getLocStart(),
+                                         TheCall->getRParenLoc());
 }
 
 /// SemaConvertVectorExpr - Handle __builtin_convertvector
@@ -1892,9 +1917,8 @@
                        << E->getSourceRange());
   }
 
-  return Owned(new (Context) ConvertVectorExpr(E, TInfo, DstTy, VK, OK,
-               BuiltinLoc, RParenLoc));
-
+  return new (Context)
+      ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);
 }
 
 /// SemaBuiltinPrefetch - Handle __builtin_prefetch.
@@ -3111,6 +3135,13 @@
         ExprTy = S.Context.CharTy;
   }
 
+  // Look through enums to their underlying type.
+  bool IsEnum = false;
+  if (auto EnumTy = ExprTy->getAs<EnumType>()) {
+    ExprTy = EnumTy->getDecl()->getIntegerType();
+    IsEnum = true;
+  }
+
   // %C in an Objective-C context prints a unichar, not a wchar_t.
   // If the argument is an integer of some kind, believe the %C and suggest
   // a cast instead of changing the conversion specifier.
@@ -3183,8 +3214,8 @@
       // In this case, the specifier is wrong and should be changed to match
       // the argument.
       EmitFormatDiagnostic(
-        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << AT.getRepresentativeTypeName(S.Context) << IntendedTy
+        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+          << AT.getRepresentativeTypeName(S.Context) << IntendedTy << IsEnum
           << E->getSourceRange(),
         E->getLocStart(),
         /*IsStringLocation*/false,
@@ -3236,7 +3267,7 @@
         StringRef Name = cast<TypedefType>(ExprTy)->getDecl()->getName();
 
         EmitFormatDiagnostic(S.PDiag(diag::warn_format_argument_needs_cast)
-                               << Name << IntendedTy
+                               << Name << IntendedTy << IsEnum
                                << E->getSourceRange(),
                              E->getLocStart(), /*IsStringLocation=*/false,
                              SpecRange, Hints);
@@ -3245,8 +3276,8 @@
         // specifier, but we've decided that the specifier is probably correct 
         // and we should cast instead. Just use the normal warning message.
         EmitFormatDiagnostic(
-          S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-            << AT.getRepresentativeTypeName(S.Context) << ExprTy
+          S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+            << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum
             << E->getSourceRange(),
           E->getLocStart(), /*IsStringLocation*/false,
           SpecRange, Hints);
@@ -3262,8 +3293,8 @@
     case Sema::VAK_Valid:
     case Sema::VAK_ValidInCXX11:
       EmitFormatDiagnostic(
-        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << AT.getRepresentativeTypeName(S.Context) << ExprTy
+        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+          << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum
           << CSR
           << E->getSourceRange(),
         E->getLocStart(), /*IsStringLocation*/false, CSR);
@@ -3454,8 +3485,8 @@
       fixedFS.toString(os);
 
       EmitFormatDiagnostic(
-        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
+        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+          << AT.getRepresentativeTypeName(S.Context) << Ex->getType() << false
           << Ex->getSourceRange(),
         Ex->getLocStart(),
         /*IsStringLocation*/false,
@@ -3465,8 +3496,8 @@
           os.str()));
     } else {
       EmitFormatDiagnostic(
-        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
+        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+          << AT.getRepresentativeTypeName(S.Context) << Ex->getType() << false
           << Ex->getSourceRange(),
         Ex->getLocStart(),
         /*IsStringLocation*/false,
@@ -3963,15 +3994,35 @@
   return true;
 }
 
-/// \brief Determine whether the given type is a dynamic class type (e.g.,
-/// whether it has a vtable).
-static bool isDynamicClassType(QualType T) {
-  if (CXXRecordDecl *Record = T->getAsCXXRecordDecl())
-    if (CXXRecordDecl *Definition = Record->getDefinition())
-      if (Definition->isDynamicClass())
-        return true;
-  
-  return false;
+/// \brief Determine whether the given type is or contains a dynamic class type
+/// (e.g., whether it has a vtable).
+static const CXXRecordDecl *getContainedDynamicClass(QualType T,
+                                                     bool &IsContained) {
+  // Look through array types while ignoring qualifiers.
+  const Type *Ty = T->getBaseElementTypeUnsafe();
+  IsContained = false;
+
+  const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+  RD = RD ? RD->getDefinition() : nullptr;
+  if (!RD)
+    return nullptr;
+
+  if (RD->isDynamicClass())
+    return RD;
+
+  // Check all the fields.  If any bases were dynamic, the class is dynamic.
+  // It's impossible for a class to transitively contain itself by value, so
+  // infinite recursion is impossible.
+  for (auto *FD : RD->fields()) {
+    bool SubContained;
+    if (const CXXRecordDecl *ContainedRD =
+            getContainedDynamicClass(FD->getType(), SubContained)) {
+      IsContained = true;
+      return ContainedRD;
+    }
+  }
+
+  return nullptr;
 }
 
 /// \brief If E is a sizeof expression, returns its argument expression,
@@ -4045,8 +4096,8 @@
       // expression IDs can be expensive, we only do this if the diagnostic is
       // enabled.
       if (SizeOfArg &&
-          Diags.getDiagnosticLevel(diag::warn_sizeof_pointer_expr_memaccess,
-                                   SizeOfArg->getExprLoc())) {
+          !Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
+                           SizeOfArg->getExprLoc())) {
         // We only compute IDs for expressions if the warning is enabled, and
         // cache the sizeof arg's ID.
         if (SizeOfArgID == llvm::FoldingSetNodeID())
@@ -4115,7 +4166,9 @@
       }
 
       // Always complain about dynamic classes.
-      if (isDynamicClassType(PointeeTy)) {
+      bool IsContained;
+      if (const CXXRecordDecl *ContainedRD =
+              getContainedDynamicClass(PointeeTy, IsContained)) {
 
         unsigned OperationType = 0;
         // "overwritten" if we're warning about the destination for any call
@@ -4133,8 +4186,7 @@
           Dest->getExprLoc(), Dest,
           PDiag(diag::warn_dyn_class_memaccess)
             << (BId == Builtin::BImemcmp ? ArgIdx + 2 : ArgIdx)
-            << FnName << PointeeTy
-            << OperationType
+            << FnName << IsContained << ContainedRD << OperationType
             << Call->getCallee()->getSourceRange());
       } else if (PointeeTy.hasNonTrivialObjCLifetime() &&
                BId != Builtin::BImemset)
@@ -4572,7 +4624,6 @@
   case Stmt::CXXReinterpretCastExprClass: {
     Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
     switch (cast<CastExpr>(E)->getCastKind()) {
-    case CK_BitCast:
     case CK_LValueToRValue:
     case CK_NoOp:
     case CK_BaseToDerived:
@@ -4587,6 +4638,14 @@
     case CK_ArrayToPointerDecay:
       return EvalVal(SubExpr, refVars, ParentDecl);
 
+    case CK_BitCast:
+      if (SubExpr->getType()->isAnyPointerType() ||
+          SubExpr->getType()->isBlockPointerType() ||
+          SubExpr->getType()->isObjCQualifiedIdType())
+        return EvalAddr(SubExpr, refVars, ParentDecl);
+      else
+        return nullptr;
+
     default:
       return nullptr;
     }
@@ -5350,7 +5409,9 @@
       if (OtherRange.NonNegative) {
         if (OtherWidth >= Value.getActiveBits())
           return;
-      } else if (!OtherRange.NonNegative && !ConstantSigned) {
+      } else { // OtherSigned
+        assert(!ConstantSigned &&
+               "Two signed types converted to unsigned types.");
         // Check to see if the constant is representable in OtherT.
         if (OtherWidth > Value.getActiveBits())
           return;
@@ -5364,8 +5425,6 @@
         // after conversion.  Relational comparison still works, but equality
         // comparisons will be tautological.
         EqualityOnly = true;
-      } else { // OtherSigned && ConstantSigned
-        assert(0 && "Two signed types converted to unsigned types.");
       }
     }
 
@@ -6047,8 +6106,7 @@
   if (!Suspicious) return;
 
   // ...but it's currently ignored...
-  if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional,
-                                 CC))
+  if (!S.Diags.isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
     return;
 
   // ...then check whether it would have warned about either of the
@@ -6152,6 +6210,38 @@
   ArrayPointer
 };
 
+// Helper function for Sema::DiagnoseAlwaysNonNullPointer.
+// Returns true when emitting a warning about taking the address of a reference.
+static bool CheckForReference(Sema &SemaRef, const Expr *E,
+                              PartialDiagnostic PD) {
+  E = E->IgnoreParenImpCasts();
+
+  const FunctionDecl *FD = nullptr;
+
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (!DRE->getDecl()->getType()->isReferenceType())
+      return false;
+  } else if (const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
+    if (!M->getMemberDecl()->getType()->isReferenceType())
+      return false;
+  } else if (const CallExpr *Call = dyn_cast<CallExpr>(E)) {
+    if (!Call->getCallReturnType()->isReferenceType())
+      return false;
+    FD = Call->getDirectCallee();
+  } else {
+    return false;
+  }
+
+  SemaRef.Diag(E->getExprLoc(), PD);
+
+  // If possible, point to location of function.
+  if (FD) {
+    SemaRef.Diag(FD->getLocation(), diag::note_reference_is_return_value) << FD;
+  }
+
+  return true;
+}
+
 /// \brief Diagnose pointers that are always non-null.
 /// \param E the expression containing the pointer
 /// \param NullKind NPCK_NotNull if E is a cast to bool, otherwise, E is
@@ -6161,6 +6251,8 @@
 void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
                                         Expr::NullPointerConstantKind NullKind,
                                         bool IsEqual, SourceRange Range) {
+  if (!E)
+    return;
 
   // Don't warn inside macros.
   if (E->getExprLoc().isMacroID())
@@ -6169,6 +6261,13 @@
 
   const bool IsCompare = NullKind != Expr::NPCK_NotNull;
 
+  if (isa<CXXThisExpr>(E)) {
+    unsigned DiagID = IsCompare ? diag::warn_this_null_compare
+                                : diag::warn_this_bool_conversion;
+    Diag(E->getExprLoc(), DiagID) << E->getSourceRange() << Range << IsEqual;
+    return;
+  }
+
   bool IsAddressOf = false;
 
   if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
@@ -6178,6 +6277,17 @@
     E = UO->getSubExpr();
   }
 
+  if (IsAddressOf) {
+    unsigned DiagID = IsCompare
+                          ? diag::warn_address_of_reference_null_compare
+                          : diag::warn_address_of_reference_bool_conversion;
+    PartialDiagnostic PD = PDiag(DiagID) << E->getSourceRange() << Range
+                                         << IsEqual;
+    if (CheckForReference(*this, E, PD)) {
+      return;
+    }
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast<DeclRefExpr>(E)) {
@@ -6194,13 +6304,9 @@
   const bool IsArray = T->isArrayType();
   const bool IsFunction = T->isFunctionType();
 
-  if (IsAddressOf) {
-    // Address of function is used to silence the function warning.
-    if (IsFunction)
-      return;
-    // Address of reference can be null.
-    if (T->isReferenceType())
-      return;
+  // Address of function is used to silence the function warning.
+  if (IsAddressOf && IsFunction) {
+    return;
   }
 
   // Found nothing.
@@ -6882,9 +6988,7 @@
 void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
   // This is actually a lot of work to potentially be doing on every
   // cast; don't do it if we're ignoring -Wcast_align (as is the default).
-  if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align,
-                                          TRange.getBegin())
-        == DiagnosticsEngine::Ignored)
+  if (getDiagnostics().isIgnored(diag::warn_cast_align, TRange.getBegin()))
     return;
 
   // Ignore dependent types.
@@ -7252,10 +7356,12 @@
   struct FindCaptureVisitor : EvaluatedExprVisitor<FindCaptureVisitor> {
     FindCaptureVisitor(ASTContext &Context, VarDecl *variable)
       : EvaluatedExprVisitor<FindCaptureVisitor>(Context),
-        Variable(variable), Capturer(nullptr) {}
-
+        Context(Context), Variable(variable), Capturer(nullptr),
+        VarWillBeReased(false) {}
+    ASTContext &Context;
     VarDecl *Variable;
     Expr *Capturer;
+    bool VarWillBeReased;
 
     void VisitDeclRefExpr(DeclRefExpr *ref) {
       if (ref->getDecl() == Variable && !Capturer)
@@ -7280,6 +7386,21 @@
       if (OVE->getSourceExpr())
         Visit(OVE->getSourceExpr());
     }
+    void VisitBinaryOperator(BinaryOperator *BinOp) {
+      if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign)
+        return;
+      Expr *LHS = BinOp->getLHS();
+      if (const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(LHS)) {
+        if (DRE->getDecl() != Variable)
+          return;
+        if (Expr *RHS = BinOp->getRHS()) {
+          RHS = RHS->IgnoreParenCasts();
+          llvm::APSInt Value;
+          VarWillBeReased =
+            (RHS && RHS->isIntegerConstantExpr(Value, Context) && Value == 0);
+        }
+      }
+    }
   };
 }
 
@@ -7317,7 +7438,7 @@
 
   FindCaptureVisitor visitor(S.Context, owner.Variable);
   visitor.Visit(block->getBlockDecl()->getBody());
-  return visitor.Capturer;
+  return visitor.VarWillBeReased ? nullptr : visitor.Capturer;
 }
 
 static void diagnoseRetainCycle(Sema &S, Expr *capturer,
@@ -7476,9 +7597,7 @@
   Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime();
 
   if (LT == Qualifiers::OCL_Weak) {
-    DiagnosticsEngine::Level Level =
-      Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, Loc);
-    if (Level != DiagnosticsEngine::Ignored)
+    if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
       getCurFunction()->markSafeWeakUse(LHS);
   }
 
@@ -7603,8 +7722,7 @@
     return;
 
   // Skip expensive checks if diagnostic is disabled.
-  if (Diags.getDiagnosticLevel(DiagID, NBody->getSemiLoc()) ==
-          DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(DiagID, NBody->getSemiLoc()))
     return;
 
   // Do the usual checks.
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index c075c92..3d250e3 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -480,6 +480,16 @@
   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) {
+  if (Id->getLength() < 2)
+    return false;
+  const char *Name = Id->getNameStart();
+  return Name[0] == '_' &&
+         (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z'));
+}
+
 bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
                                       bool &AsNestedNameSpecifier) const {
   AsNestedNameSpecifier = false;
@@ -506,25 +516,15 @@
     return false;
   
   // Some declarations have reserved names that we don't want to ever show.
-  if (const IdentifierInfo *Id = ND->getIdentifier()) {
-    // __va_list_tag is a freak of nature. Find it and skip it.
-    if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
-      return false;
-    
-    // Filter out names reserved for the implementation (C99 7.1.3, 
-    // C++ [lib.global.names]) if they come from a system header.
-    //
-    // FIXME: Add predicate for this.
-    if (Id->getLength() >= 2) {
-      const char *Name = Id->getNameStart();
-      if (Name[0] == '_' &&
-          (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
-          (ND->getLocation().isInvalid() ||
-           SemaRef.SourceMgr.isInSystemHeader(
-                          SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
+  // Filter out names reserved for the implementation if they come from a
+  // system header.
+  // TODO: Add a predicate for this.
+  if (const IdentifierInfo *Id = ND->getIdentifier())
+    if (isReservedName(Id) &&
+        (ND->getLocation().isInvalid() ||
+         SemaRef.SourceMgr.isInSystemHeader(
+             SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
         return false;
-    }
-  }
 
   if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
       ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
@@ -3428,7 +3428,7 @@
   if (E.isInvalid())
     CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
   else if (getLangOpts().ObjC1)
-    CodeCompleteObjCInstanceMessage(S, E.take(), None, false);
+    CodeCompleteObjCInstanceMessage(S, E.get(), None, false);
 }
 
 /// \brief The set of properties that have already been added, referenced by
@@ -5322,7 +5322,7 @@
       if (R.Priority <= BestPriority) {
         const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
         if (NumSelIdents <= Method->param_size()) {
-          QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
+          QualType MyPreferredType = Method->parameters()[NumSelIdents - 1]
                                        ->getType();
           if (R.Priority < BestPriority || PreferredType.isNull()) {
             BestPriority = R.Priority;
@@ -5466,7 +5466,7 @@
     ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
     if (Conv.isInvalid()) // conversion failed. bail.
       return;
-    RecExpr = Conv.take();
+    RecExpr = Conv.get();
   }
   QualType ReceiverType = RecExpr? RecExpr->getType() 
                           : Super? Context.getObjCObjectPointerType(
@@ -5490,7 +5490,7 @@
   } else if (RecExpr && getLangOpts().CPlusPlus) {
     ExprResult Conv = PerformContextuallyConvertToObjCPointer(RecExpr);
     if (Conv.isUsable()) {
-      RecExpr = Conv.take();
+      RecExpr = Conv.get();
       ReceiverType = RecExpr->getType();
     }
   }
@@ -6994,7 +6994,7 @@
         // Suggest parameter names we've seen before.
         unsigned NumSelIdents = SelIdents.size();
         if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
-          ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
+          ParmVarDecl *Param = MethList->Method->parameters()[NumSelIdents-1];
           if (Param->getIdentifier()) {
             CodeCompletionBuilder Builder(Results.getAllocator(),
                                           Results.getCodeCompletionTUInfo());
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index a0ce766..13a77f1 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -128,6 +128,65 @@
   return false;
 }
 
+static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,
+                                                      const IdentifierInfo &II,
+                                                      SourceLocation NameLoc) {
+  // Find the first parent class template context, if any.
+  // FIXME: Perform the lookup in all enclosing class templates.
+  const CXXRecordDecl *RD = nullptr;
+  for (DeclContext *DC = S.CurContext; DC; DC = DC->getParent()) {
+    RD = dyn_cast<CXXRecordDecl>(DC);
+    if (RD && RD->getDescribedClassTemplate())
+      break;
+  }
+  if (!RD)
+    return ParsedType();
+
+  // Look for type decls in dependent base classes that have known primary
+  // templates.
+  bool FoundTypeDecl = false;
+  for (const auto &Base : RD->bases()) {
+    auto *TST = Base.getType()->getAs<TemplateSpecializationType>();
+    if (!TST || !TST->isDependentType())
+      continue;
+    auto *TD = TST->getTemplateName().getAsTemplateDecl();
+    if (!TD)
+      continue;
+    auto *BasePrimaryTemplate = cast<CXXRecordDecl>(TD->getTemplatedDecl());
+    // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly
+    // by calling or integrating with the main LookupQualifiedName mechanism.
+    for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) {
+      if (FoundTypeDecl)
+        return ParsedType();
+      FoundTypeDecl = isa<TypeDecl>(ND);
+      if (!FoundTypeDecl)
+        return ParsedType();
+    }
+  }
+  if (!FoundTypeDecl)
+    return ParsedType();
+
+  // We found some types in dependent base classes.  Recover as if the user
+  // wrote 'typename MyClass::II' instead of 'II'.  We'll fully resolve the
+  // lookup during template instantiation.
+  S.Diag(NameLoc, diag::ext_found_via_dependent_bases_lookup) << &II;
+
+  ASTContext &Context = S.Context;
+  auto *NNS = NestedNameSpecifier::Create(Context, nullptr, false,
+                                          cast<Type>(Context.getRecordType(RD)));
+  QualType T = Context.getDependentNameType(ETK_Typename, NNS, &II);
+
+  CXXScopeSpec SS;
+  SS.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+
+  TypeLocBuilder Builder;
+  DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+  DepTL.setNameLoc(NameLoc);
+  DepTL.setElaboratedKeywordLoc(SourceLocation());
+  DepTL.setQualifierLoc(SS.getWithLocInContext(Context));
+  return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
 /// \brief If the identifier refers to a type name within this scope,
 /// return the declaration of that type.
 ///
@@ -209,6 +268,14 @@
   } else {
     // Perform unqualified name lookup.
     LookupName(Result, S);
+
+    // For unqualified lookup in a class template in MSVC mode, look into
+    // dependent base classes where the primary class template is known.
+    if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) {
+      if (ParsedType TypeInBase =
+              recoverFromTypeInKnownDependentBase(*this, II, NameLoc))
+        return TypeInBase;
+    }
   }
 
   NamedDecl *IIDecl = nullptr;
@@ -343,6 +410,50 @@
   return ParsedType::make(T);
 }
 
+// Builds a fake NNS for the given decl context.
+static NestedNameSpecifier *
+synthesizeCurrentNestedNameSpecifier(ASTContext &Context, DeclContext *DC) {
+  for (;; DC = DC->getLookupParent()) {
+    DC = DC->getPrimaryContext();
+    auto *ND = dyn_cast<NamespaceDecl>(DC);
+    if (ND && !ND->isInline() && !ND->isAnonymousNamespace())
+      return NestedNameSpecifier::Create(Context, nullptr, ND);
+    else if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
+      return NestedNameSpecifier::Create(Context, nullptr, RD->isTemplateDecl(),
+                                         RD->getTypeForDecl());
+    else if (isa<TranslationUnitDecl>(DC))
+      return NestedNameSpecifier::GlobalSpecifier(Context);
+  }
+  llvm_unreachable("something isn't in TU scope?");
+}
+
+ParsedType Sema::ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II,
+                                                SourceLocation NameLoc) {
+  // Accepting an undeclared identifier as a default argument for a template
+  // type parameter is a Microsoft extension.
+  Diag(NameLoc, diag::ext_ms_delayed_template_argument) << &II;
+
+  // Build a fake DependentNameType that will perform lookup into CurContext at
+  // instantiation time.  The name specifier isn't dependent, so template
+  // instantiation won't transform it.  It will retry the lookup, however.
+  NestedNameSpecifier *NNS =
+      synthesizeCurrentNestedNameSpecifier(Context, CurContext);
+  QualType T = Context.getDependentNameType(ETK_None, NNS, &II);
+
+  // Build type location information.  We synthesized the qualifier, so we have
+  // to build a fake NestedNameSpecifierLoc.
+  NestedNameSpecifierLocBuilder NNSLocBuilder;
+  NNSLocBuilder.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+  NestedNameSpecifierLoc QualifierLoc = NNSLocBuilder.getWithLocInContext(Context);
+
+  TypeLocBuilder Builder;
+  DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+  DepTL.setNameLoc(NameLoc);
+  DepTL.setElaboratedKeywordLoc(SourceLocation());
+  DepTL.setQualifierLoc(QualifierLoc);
+  return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
 /// isTagName() - This method is called *for error recovery purposes only*
 /// to determine if the specified name is a valid tag name ("struct foo").  If
 /// so, this returns the TST for the tag corresponding to it (TST_enum,
@@ -394,7 +505,7 @@
   return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope();
 }
 
-bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
+void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
                                    SourceLocation IILoc,
                                    Scope *S,
                                    CXXScopeSpec *SS,
@@ -439,7 +550,7 @@
                                   /*IsCtorOrDtorName=*/false,
                                   /*NonTrivialTypeSourceInfo=*/true);
     }
-    return true;
+    return;
   }
 
   if (getLangOpts().CPlusPlus) {
@@ -458,7 +569,7 @@
         Diag(TplDecl->getLocation(), diag::note_template_decl_here)
           << TplDecl->getTemplateParameters()->getSourceRange();
       }
-      return true;
+      return;
     }
   }
 
@@ -473,7 +584,7 @@
   else if (isDependentScopeSpecifier(*SS)) {
     unsigned DiagID = diag::err_typename_missing;
     if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S))
-      DiagID = diag::warn_typename_missing;
+      DiagID = diag::ext_typename_missing;
 
     Diag(SS->getRange().getBegin(), DiagID)
       << SS->getScopeRep() << II->getName()
@@ -485,8 +596,6 @@
     assert(SS && SS->isInvalid() && 
            "Invalid scope specifier has already been diagnosed");
   }
-  
-  return true;
 }
 
 /// \brief Determine whether the given result set contains either a type name
@@ -588,6 +697,14 @@
   LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
   LookupParsedName(Result, S, &SS, !CurMethod);
 
+  // For unqualified lookup in a class template in MSVC mode, look into
+  // dependent base classes where the primary class template is known.
+  if (Result.empty() && SS.isEmpty() && getLangOpts().MSVCCompat) {
+    if (ParsedType TypeInBase =
+            recoverFromTypeInKnownDependentBase(*this, *Name, NameLoc))
+      return TypeInBase;
+  }
+
   // Perform lookup for Objective-C instance variables (including automatically 
   // synthesized instance variables), if we're in an Objective-C method.
   // FIXME: This lookup really, really needs to be folded in to the normal
@@ -1527,8 +1644,7 @@
       << Context.BuiltinInfo.GetName(BID)
       << R;
     if (Context.BuiltinInfo.getHeaderName(BID) &&
-        Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl, Loc)
-          != DiagnosticsEngine::Ignored)
+        !Diags.isIgnored(diag::ext_implicit_lib_function_decl, Loc))
       Diag(Loc, diag::note_please_include_header)
         << Context.BuiltinInfo.getHeaderName(BID)
         << Context.BuiltinInfo.GetName(BID);
@@ -2210,6 +2326,24 @@
   return Sema::CXXInvalid;
 }
 
+// Determine whether the previous declaration was a definition, implicit
+// declaration, or a declaration.
+template <typename T>
+static std::pair<diag::kind, SourceLocation>
+getNoteDiagForInvalidRedeclaration(const T *Old, const T *New) {
+  diag::kind PrevDiag;
+  SourceLocation OldLocation = Old->getLocation();
+  if (Old->isThisDeclarationADefinition())
+    PrevDiag = diag::note_previous_definition;
+  else if (Old->isImplicit()) {
+    PrevDiag = diag::note_previous_implicit_declaration;
+    if (OldLocation.isInvalid())
+      OldLocation = New->getLocation();
+  } else
+    PrevDiag = diag::note_previous_declaration;
+  return std::make_pair(PrevDiag, OldLocation);
+}
+
 /// canRedefineFunction - checks if a function can be redefined. Currently,
 /// only extern inline functions can be redefined, and even then only in
 /// GNU89 mode.
@@ -2302,18 +2436,10 @@
   if (Old->isInvalidDecl())
     return true;
 
-  // Determine whether the previous declaration was a definition,
-  // implicit declaration, or a declaration.
   diag::kind PrevDiag;
-  SourceLocation OldLocation = Old->getLocation();
-  if (Old->isThisDeclarationADefinition())
-    PrevDiag = diag::note_previous_definition;
-  else if (Old->isImplicit()) {
-    PrevDiag = diag::note_previous_implicit_declaration;
-    if (OldLocation.isInvalid())
-      OldLocation = New->getLocation();
-  } else
-    PrevDiag = diag::note_previous_declaration;
+  SourceLocation OldLocation;
+  std::tie(PrevDiag, OldLocation) =
+      getNoteDiagForInvalidRedeclaration(Old, New);
 
   // Don't complain about this if we're in GNU89 mode and the old function
   // is an extern inline function.
@@ -2325,7 +2451,7 @@
       !New->getTemplateSpecializationInfo() &&
       !canRedefineFunction(Old, getLangOpts())) {
     if (getLangOpts().MicrosoftExt) {
-      Diag(New->getLocation(), diag::warn_static_non_static) << New;
+      Diag(New->getLocation(), diag::ext_static_non_static) << New;
       Diag(OldLocation, PrevDiag);
     } else {
       Diag(New->getLocation(), diag::err_static_non_static) << New;
@@ -2468,11 +2594,13 @@
         ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType);
       if (ResQT.isNull()) {
         if (New->isCXXClassMember() && New->isOutOfLine())
-          Diag(New->getLocation(),
-               diag::err_member_def_does_not_match_ret_type) << New;
+          Diag(New->getLocation(), diag::err_member_def_does_not_match_ret_type)
+              << New << New->getReturnTypeSourceRange();
         else
-          Diag(New->getLocation(), diag::err_ovl_diff_return_type);
-        Diag(OldLocation, PrevDiag) << Old << Old->getType();
+          Diag(New->getLocation(), diag::err_ovl_diff_return_type)
+              << New->getReturnTypeSourceRange();
+        Diag(OldLocation, PrevDiag) << Old << Old->getType()
+                                    << Old->getReturnTypeSourceRange();
         return true;
       }
       else
@@ -3026,13 +3154,25 @@
   if (New->isInvalidDecl())
     return;
 
+  diag::kind PrevDiag;
+  SourceLocation OldLocation;
+  std::tie(PrevDiag, OldLocation) =
+      getNoteDiagForInvalidRedeclaration(Old, New);
+
   // [dcl.stc]p8: Check if we have a non-static decl followed by a static.
   if (New->getStorageClass() == SC_Static &&
       !New->isStaticDataMember() &&
       Old->hasExternalFormalLinkage()) {
-    Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
-    return New->setInvalidDecl();
+    if (getLangOpts().MicrosoftExt) {
+      Diag(New->getLocation(), diag::ext_static_non_static)
+          << New->getDeclName();
+      Diag(OldLocation, PrevDiag);
+    } else {
+      Diag(New->getLocation(), diag::err_static_non_static)
+          << New->getDeclName();
+      Diag(OldLocation, PrevDiag);
+      return New->setInvalidDecl();
+    }
   }
   // C99 6.2.2p4:
   //   For an identifier declared with the storage-class specifier
@@ -3049,7 +3189,7 @@
            !New->isStaticDataMember() &&
            Old->getCanonicalDecl()->getStorageClass() == SC_Static) {
     Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     return New->setInvalidDecl();
   }
 
@@ -3057,13 +3197,13 @@
   if (New->hasExternalStorage() &&
       !Old->hasLinkage() && Old->isLocalVarDecl()) {
     Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     return New->setInvalidDecl();
   }
   if (Old->hasLinkage() && New->isLocalVarDecl() &&
       !New->hasExternalStorage()) {
     Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     return New->setInvalidDecl();
   }
 
@@ -3076,17 +3216,17 @@
       !(Old->getLexicalDeclContext()->isRecord() &&
         !New->getLexicalDeclContext()->isRecord())) {
     Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     return New->setInvalidDecl();
   }
 
   if (New->getTLSKind() != Old->getTLSKind()) {
     if (!Old->getTLSKind()) {
       Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();
-      Diag(Old->getLocation(), diag::note_previous_declaration);
+      Diag(OldLocation, PrevDiag);
     } else if (!New->getTLSKind()) {
       Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
-      Diag(Old->getLocation(), diag::note_previous_declaration);
+      Diag(OldLocation, PrevDiag);
     } else {
       // Do not allow redeclaration to change the variable between requiring
       // static and dynamic initialization.
@@ -3094,7 +3234,7 @@
       // declaration to determine the kind. Do we need to be compatible here?
       Diag(New->getLocation(), diag::err_thread_thread_different_kind)
         << New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic);
-      Diag(Old->getLocation(), diag::note_previous_declaration);
+      Diag(OldLocation, PrevDiag);
     }
   }
 
@@ -3111,7 +3251,7 @@
 
   if (haveIncompatibleLanguageLinkages(Old, New)) {
     Diag(New->getLocation(), diag::err_different_language_linkage) << New;
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     New->setInvalidDecl();
     return;
   }
@@ -3691,6 +3831,8 @@
         }
       } else if (isa<AccessSpecDecl>(Mem)) {
         // Any access specifier is fine.
+      } else if (isa<StaticAssertDecl>(Mem)) {
+        // In C++1z, static_assert declarations are also fine.
       } else {
         // We have something that isn't a non-static data
         // member. Complain about it.
@@ -4907,10 +5049,15 @@
   // A redeclaration is not allowed to drop a dllimport attribute, the only
   // exception being inline function definitions.
   // NB: MSVC converts such a declaration to dllexport.
-  bool IsInline =
-      isa<FunctionDecl>(NewDecl) && cast<FunctionDecl>(NewDecl)->isInlined();
+  bool IsInline = false, IsStaticDataMember = false;
+  if (const auto *VD = dyn_cast<VarDecl>(NewDecl))
+    // Ignore static data because out-of-line definitions are diagnosed
+    // separately.
+    IsStaticDataMember = VD->isStaticDataMember();
+  else if (const auto *FD = dyn_cast<FunctionDecl>(NewDecl))
+    IsInline = FD->isInlined();
 
-  if (OldImportAttr && !HasNewAttr && !IsInline) {
+  if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember) {
     S.Diag(NewDecl->getLocation(),
            diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
       << NewDecl << OldImportAttr;
@@ -5453,6 +5600,10 @@
       // Global Named register
       if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
         Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
+      if (!R->isIntegralType(Context) && !R->isPointerType()) {
+        Diag(D.getLocStart(), diag::err_asm_bad_register_type);
+        NewVD->setInvalidDecl(true);
+      }
     }
 
     NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
@@ -5590,8 +5741,7 @@
 ///
 void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
   // Return if warning is ignored.
-  if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, R.getNameLoc()) ==
-        DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
     return;
 
   // Don't diagnose declarations at file scope.
@@ -5664,8 +5814,7 @@
 
 /// \brief Check -Wshadow without the advantage of a previous lookup.
 void Sema::CheckShadow(Scope *S, VarDecl *D) {
-  if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, D->getLocation()) ==
-        DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_decl_shadow, D->getLocation()))
     return;
 
   LookupResult R(*this, D->getDeclName(), D->getLocation(),
@@ -7422,8 +7571,10 @@
     
     // OpenCL v1.2, s6.9 -- Kernels can only have return type void.
     if (!NewFD->getReturnType()->isVoidType()) {
-      Diag(D.getIdentifierLoc(),
-           diag::err_expected_kernel_void_return_type);
+      SourceRange RTRange = NewFD->getReturnTypeSourceRange();
+      Diag(D.getIdentifierLoc(), diag::err_expected_kernel_void_return_type)
+          << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
+                                : FixItHint());
       D.setInvalidType();
     }
 
@@ -7763,23 +7914,6 @@
   return Redeclaration;
 }
 
-static SourceRange getResultSourceRange(const FunctionDecl *FD) {
-  const TypeSourceInfo *TSI = FD->getTypeSourceInfo();
-  if (!TSI)
-    return SourceRange();
-
-  TypeLoc TL = TSI->getTypeLoc();
-  FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>();
-  if (!FunctionTL)
-    return SourceRange();
-
-  TypeLoc ResultTL = FunctionTL.getReturnLoc();
-  if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>())
-    return ResultTL.getSourceRange();
-
-  return SourceRange();
-}
-
 void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
   // C++11 [basic.start.main]p3:
   //   A program that [...] declares main to be inline, static or
@@ -7819,34 +7953,37 @@
   assert(T->isFunctionType() && "function decl is not of function type");
   const FunctionType* FT = T->castAs<FunctionType>();
 
-  // All the standards say that main() should should return 'int'.
-  if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy)) {
+  if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
+    // In C with GNU extensions we allow main() to have non-integer return
+    // type, but we should warn about the extension, and we disable the
+    // implicit-return-zero rule.
+
+    // GCC in C mode accepts qualified 'int'.
+    if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy))
+      FD->setHasImplicitReturnZero(true);
+    else {
+      Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
+      SourceRange RTRange = FD->getReturnTypeSourceRange();
+      if (RTRange.isValid())
+        Diag(RTRange.getBegin(), diag::note_main_change_return_type)
+            << FixItHint::CreateReplacement(RTRange, "int");
+    }
+  } else {
     // In C and C++, main magically returns 0 if you fall off the end;
     // set the flag which tells us that.
     // This is C++ [basic.start.main]p5 and C99 5.1.2.2.3.
-    FD->setHasImplicitReturnZero(true);
 
-  // In C with GNU extensions we allow main() to have non-integer return
-  // type, but we should warn about the extension, and we disable the
-  // implicit-return-zero rule.
-  } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
-    Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
-
-    SourceRange ResultRange = getResultSourceRange(FD);
-    if (ResultRange.isValid())
-      Diag(ResultRange.getBegin(), diag::note_main_change_return_type)
-          << FixItHint::CreateReplacement(ResultRange, "int");
-
-  // Otherwise, this is just a flat-out error.
-  } else {
-    SourceRange ResultRange = getResultSourceRange(FD);
-    if (ResultRange.isValid())
+    // All the standards say that main() should return 'int'.
+    if (Context.hasSameType(FT->getReturnType(), Context.IntTy))
+      FD->setHasImplicitReturnZero(true);
+    else {
+      // Otherwise, this is just a flat-out error.
+      SourceRange RTRange = FD->getReturnTypeSourceRange();
       Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint)
-          << FixItHint::CreateReplacement(ResultRange, "int");
-    else
-      Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
-
-    FD->setInvalidDecl(true);
+          << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int")
+                                : FixItHint());
+      FD->setInvalidDecl(true);
+    }
   }
 
   // Treat protoless main() as nullary.
@@ -8197,7 +8334,7 @@
         VDecl->setInvalidDecl();
         return;
       }
-      Init = Result.take();
+      Init = Result.get();
       DefaultedToAuto = true;
     }
 
@@ -8336,7 +8473,7 @@
       VDecl->setInvalidDecl();
       return;
     }
-    Init = Result.take();
+    Init = Result.get();
   }
 
   // Perform the initialization.
@@ -8364,7 +8501,7 @@
       return;
     }
 
-    Init = Result.takeAs<Expr>();
+    Init = Result.getAs<Expr>();
   }
 
   // Check for self-references within variable initializers.
@@ -8395,13 +8532,10 @@
     // we do not warn to warn spuriously when 'x' and 'y' are on separate
     // paths through the function. This should be revisited if
     // -Wrepeated-use-of-weak is made flow-sensitive.
-    if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
-      DiagnosticsEngine::Level Level =
-        Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                 Init->getLocStart());
-      if (Level != DiagnosticsEngine::Ignored)
+    if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong &&
+        !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+                         Init->getLocStart()))
         getCurFunction()->markSafeWeakUse(Init);
-    }
   }
 
   // The initialization is usually a full-expression.
@@ -8422,7 +8556,7 @@
     VDecl->setInvalidDecl();
     return;
   }
-  Init = Result.take();
+  Init = Result.get();
 
   // Attach the initializer to the decl.
   VDecl->setInit(Init);
@@ -8763,11 +8897,13 @@
     if (Var->isInvalidDecl())
       return;
 
-    if (RequireCompleteType(Var->getLocation(), 
-                            Context.getBaseElementType(Type),
-                            diag::err_typecheck_decl_incomplete_type)) {
-      Var->setInvalidDecl();
-      return;
+    if (!Var->hasAttr<AliasAttr>()) {
+      if (RequireCompleteType(Var->getLocation(),
+                              Context.getBaseElementType(Type),
+                              diag::err_typecheck_decl_incomplete_type)) {
+        Var->setInvalidDecl();
+        return;
+      }
     }
 
     // The variable can not have an abstract class type.
@@ -8874,6 +9010,37 @@
   }
 }
 
+StmtResult
+Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
+                                 IdentifierInfo *Ident,
+                                 ParsedAttributes &Attrs,
+                                 SourceLocation AttrEnd) {
+  // C++1y [stmt.iter]p1:
+  //   A range-based for statement of the form
+  //      for ( for-range-identifier : for-range-initializer ) statement
+  //   is equivalent to
+  //      for ( auto&& for-range-identifier : for-range-initializer ) statement
+  DeclSpec DS(Attrs.getPool().getFactory());
+
+  const char *PrevSpec;
+  unsigned DiagID;
+  DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID,
+                     getPrintingPolicy());
+
+  Declarator D(DS, Declarator::ForContext);
+  D.SetIdentifier(Ident, IdentLoc);
+  D.takeAttributes(Attrs, AttrEnd);
+
+  ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory());
+  D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/false),
+                EmptyAttrs, IdentLoc);
+  Decl *Var = ActOnDeclarator(S, D);
+  cast<VarDecl>(Var)->setCXXForRangeDecl(true);
+  FinalizeDeclaration(Var);
+  return ActOnDeclStmt(FinalizeDeclaratorGroup(S, DS, Var), IdentLoc,
+                       AttrEnd.isValid() ? AttrEnd : IdentLoc);
+}
+
 void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
   if (var->isInvalidDecl()) return;
 
@@ -8902,9 +9069,8 @@
   if (var->isThisDeclarationADefinition() &&
       var->getDeclContext()->getRedeclContext()->isFileContext() &&
       var->isExternallyVisible() && var->hasLinkage() &&
-      getDiagnostics().getDiagnosticLevel(
-                       diag::warn_missing_variable_declarations,
-                       var->getLocation())) {
+      !getDiagnostics().isIgnored(diag::warn_missing_variable_declarations,
+                                  var->getLocation())) {
     // Find a previous declaration that's not a definition.
     VarDecl *prev = var->getPreviousDecl();
     while (prev && prev->isThisDeclarationADefinition())
@@ -8984,7 +9150,7 @@
             var, var->getType(), varRef, /*AllowNRVO=*/true);
       if (!result.isInvalid()) {
         result = MaybeCreateExprWithCleanups(result);
-        Expr *init = result.takeAs<Expr>();
+        Expr *init = result.getAs<Expr>();
         Context.setBlockVarCopyInits(var, init);
       }
     }
@@ -8997,9 +9163,8 @@
   if (!var->getDeclContext()->isDependentContext() &&
       Init && !Init->isValueDependent()) {
     if (IsGlobal && !var->isConstexpr() &&
-        getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor,
-                                            var->getLocation())
-          != DiagnosticsEngine::Ignored) {
+        !getDiagnostics().isIgnored(diag::warn_global_constructor,
+                                    var->getLocation())) {
       // Warn about globals which don't have a constant initializer.  Don't
       // warn about globals with a non-trivial destructor because we already
       // warned about them.
@@ -9052,6 +9217,40 @@
 
   checkAttributesAfterMerging(*this, *VD);
 
+  // Static locals inherit dll attributes from their function.
+  if (VD->isStaticLocal()) {
+    if (FunctionDecl *FD =
+            dyn_cast<FunctionDecl>(VD->getParentFunctionOrMethod())) {
+      if (Attr *A = getDLLAttr(FD)) {
+        auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext()));
+        NewAttr->setInherited(true);
+        VD->addAttr(NewAttr);
+      }
+    }
+  }
+
+  // Imported static data members cannot be defined out-of-line.
+  if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) {
+    if (VD->isStaticDataMember() && VD->isOutOfLine() &&
+        VD->isThisDeclarationADefinition()) {
+      // We allow definitions of dllimport class template static data members
+      // with a warning.
+      CXXRecordDecl *Context =
+        cast<CXXRecordDecl>(VD->getFirstDecl()->getDeclContext());
+      bool IsClassTemplateMember =
+          isa<ClassTemplatePartialSpecializationDecl>(Context) ||
+          Context->getDescribedClassTemplate();
+
+      Diag(VD->getLocation(),
+           IsClassTemplateMember
+               ? diag::warn_attribute_dllimport_static_field_definition
+               : diag::err_attribute_dllimport_static_field_definition);
+      Diag(IA->getLocation(), diag::note_attribute);
+      if (!IsClassTemplateMember)
+        VD->setInvalidDecl();
+    }
+  }
+
   if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
     if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
       Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
@@ -9145,7 +9344,7 @@
 /// BuildDeclaratorGroup - convert a list of declarations into a declaration
 /// group, performing any necessary semantic checking.
 Sema::DeclGroupPtrTy
-Sema::BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group,
+Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
                            bool TypeMayContainAuto) {
   // C++0x [dcl.spec.auto]p7:
   //   If the type deduced for the template parameter U is not the same in each
@@ -9202,9 +9401,7 @@
   if (Group.empty() || !Group[0])
    return;
 
-  if (Diags.getDiagnosticLevel(diag::warn_doc_param_not_found,
-                               Group[0]->getLocation())
-        == DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_doc_param_not_found, Group[0]->getLocation()))
     return;
 
   if (Group.size() >= 2) {
@@ -9797,6 +9994,11 @@
   // We want to attach documentation to original Decl (which might be
   // a function template).
   ActOnDocumentableDecl(D);
+  if (getCurLexicalContext()->isObjCContainer() &&
+      getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
+      getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation)
+    Diag(FD->getLocation(), diag::warn_function_def_in_objc_container);
+    
   return D;
 }
 
@@ -10739,11 +10941,6 @@
       while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC))
         SearchDC = SearchDC->getParent();
     }
-  } else if (S->isFunctionPrototypeScope()) {
-    // If this is an enum declaration in function prototype scope, set its
-    // initial context to the translation unit.
-    // FIXME: [citation needed]
-    SearchDC = Context.getTranslationUnitDecl();
   }
 
   if (Previous.isSingleResult() &&
@@ -11216,27 +11413,37 @@
     else if (!SearchDC->isFunctionOrMethod())
       New->setModulePrivate();
   }
-  
+
   // If this is a specialization of a member class (of a class template),
   // check the specialization.
   if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
     Invalid = true;
-           
+
+  // If we're declaring or defining a tag in function prototype scope in C,
+  // note that this type can only be used within the function and add it to
+  // the list of decls to inject into the function definition scope.
+  if ((Name || Kind == TTK_Enum) &&
+      getNonFieldDeclScope(S)->isFunctionPrototypeScope()) {
+    if (getLangOpts().CPlusPlus) {
+      // C++ [dcl.fct]p6:
+      //   Types shall not be defined in return or parameter types.
+      if (TUK == TUK_Definition && !IsTypeSpecifier) {
+        Diag(Loc, diag::err_type_defined_in_param_type)
+            << Name;
+        Invalid = true;
+      }
+    } else {
+      Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+    }
+    DeclsInPrototypeScope.push_back(New);
+  }
+
   if (Invalid)
     New->setInvalidDecl();
 
   if (Attr)
     ProcessDeclAttributeList(S, New, Attr);
 
-  // If we're declaring or defining a tag in function prototype scope in C,
-  // note that this type can only be used within the function and add it to
-  // the list of decls to inject into the function definition scope.
-  if (!getLangOpts().CPlusPlus && (Name || Kind == TTK_Enum) &&
-      getNonFieldDeclScope(S)->isFunctionPrototypeScope()) {
-    Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
-    DeclsInPrototypeScope.push_back(New);
-  }
-
   // Set the lexical context. If the tag has a C++ scope specifier, the
   // lexical context will be different from the semantic context.
   New->setLexicalDeclContext(CurContext);
@@ -11448,13 +11655,13 @@
   // If the bit-width is type- or value-dependent, don't try to check
   // it now.
   if (BitWidth->isValueDependent() || BitWidth->isTypeDependent())
-    return Owned(BitWidth);
+    return BitWidth;
 
   llvm::APSInt Value;
   ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value);
   if (ICE.isInvalid())
     return ICE;
-  BitWidth = ICE.take();
+  BitWidth = ICE.get();
 
   if (Value != 0 && ZeroWidth)
     *ZeroWidth = false;
@@ -11495,7 +11702,7 @@
     }
   }
 
-  return Owned(BitWidth);
+  return BitWidth;
 }
 
 /// ActOnField - Each field of a C struct/union is passed into this in order
@@ -11694,7 +11901,7 @@
   // If this is declared as a bit-field, check the bit-field.
   if (!InvalidDecl && BitWidth) {
     BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth,
-                              &ZeroWidth).take();
+                              &ZeroWidth).get();
     if (!BitWidth) {
       InvalidDecl = true;
       BitWidth = nullptr;
@@ -11882,7 +12089,7 @@
 
   if (BitWidth) {
     // 6.7.2.1p3, 6.7.2.1p4
-    BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).take();
+    BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).get();
     if (!BitWidth)
       D.setInvalidType();
   } else {
@@ -12483,7 +12690,7 @@
     Val = nullptr;
 
   if (Val)
-    Val = DefaultLvalueConversion(Val).take();
+    Val = DefaultLvalueConversion(Val).get();
 
   if (Val) {
     if (Enum->isDependentType() || Val->isTypeDependent())
@@ -12502,10 +12709,10 @@
         if (Converted.isInvalid())
           Val = nullptr;
         else
-          Val = Converted.take();
+          Val = Converted.get();
       } else if (!Val->isValueDependent() &&
                  !(Val = VerifyIntegerConstantExpression(Val,
-                                                         &EnumVal).take())) {
+                                                         &EnumVal).get())) {
         // C99 6.7.2.2p2: Make sure we have an integer constant expression.
       } else {
         if (Enum->isFixed()) {
@@ -12518,11 +12725,11 @@
           if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
             if (getLangOpts().MSVCCompat) {
               Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
-              Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
+              Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get();
             } else
               Diag(IdLoc, diag::err_enumerator_too_large) << EltTy;
           } else
-            Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
+            Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get();
         } else if (getLangOpts().CPlusPlus) {
           // C++11 [dcl.enum]p5:
           //   If the underlying type is not fixed, the type of each enumerator
@@ -12543,7 +12750,7 @@
               << (EnumVal.isUnsigned() || EnumVal.isNonNegative());
           else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
             // Force the type of the expression to 'int'.
-            Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take();
+            Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).get();
           }
           EltTy = Val->getType();
         }
@@ -12778,9 +12985,7 @@
 static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
                                         EnumDecl *Enum,
                                         QualType EnumType) {
-  if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values,
-                                 Enum->getLocation()) ==
-      DiagnosticsEngine::Ignored)
+  if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation()))
     return;
   // Avoid anonymous enums
   if (!Enum->getIdentifier())
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 6a85c38..31beb0b 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -85,7 +85,7 @@
   if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
     return BD->getParamDecl(Idx)->getType();
 
-  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
+  return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
 }
 
 static QualType getFunctionOrMethodResultType(const Decl *D) {
@@ -751,7 +751,7 @@
     ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
     if (Converted.isInvalid())
       return;
-    Cond = Converted.take();
+    Cond = Converted.get();
   }
 
   StringRef Msg;
@@ -2797,7 +2797,7 @@
   }
 
   AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
-                                                ICE.take(), SpellingListIndex);
+                                                ICE.get(), SpellingListIndex);
   AA->setPackExpansion(IsPackExpansion);
   D->addAttr(AA);
 }
@@ -3039,16 +3039,11 @@
 static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   FunctionDecl *FD = cast<FunctionDecl>(D);
   if (!FD->getReturnType()->isVoidType()) {
-    TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
-    if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
-      S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
+    SourceRange RTRange = FD->getReturnTypeSourceRange();
+    S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
         << FD->getType()
-        << FixItHint::CreateReplacement(FTL.getReturnLoc().getSourceRange(),
-                                        "void");
-    } else {
-      S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
-        << FD->getType();
-    }
+        << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
+                              : FixItHint());
     return;
   }
 
@@ -3358,6 +3353,11 @@
 // Checker-specific attribute handlers.
 //===----------------------------------------------------------------------===//
 
+static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType type) {
+  return type->isDependentType() ||
+         type->isObjCRetainableType();
+}
+
 static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
   return type->isDependentType() || 
          type->isObjCObjectPointerType() || 
@@ -3422,8 +3422,12 @@
   bool cf;
   switch (Attr.getKind()) {
   default: llvm_unreachable("invalid ownership attribute");
-  case AttributeList::AT_NSReturnsAutoreleased:
   case AttributeList::AT_NSReturnsRetained:
+    typeOK = isValidSubjectOfNSReturnsRetainedAttribute(returnType);
+    cf = false;
+    break;
+      
+  case AttributeList::AT_NSReturnsAutoreleased:
   case AttributeList::AT_NSReturnsNotRetained:
     typeOK = isValidSubjectOfNSAttribute(S, returnType);
     cf = false;
@@ -3845,13 +3849,6 @@
   return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex);
 }
 
-static void handleDLLImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  unsigned Index = Attr.getAttributeSpellingListIndex();
-  DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange(), Index);
-  if (NewAttr)
-    D->addAttr(NewAttr);
-}
-
 DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
                                         unsigned AttrSpellingListIndex) {
   if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
@@ -3865,9 +3862,18 @@
   return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex);
 }
 
-static void handleDLLExportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  unsigned Index = Attr.getAttributeSpellingListIndex();
-  DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange(), Index);
+static void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) {
+  if (isa<ClassTemplatePartialSpecializationDecl>(D) &&
+      S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+    S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored)
+        << A.getName();
+    return;
+  }
+
+  unsigned Index = A.getAttributeSpellingListIndex();
+  Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport
+                      ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index)
+                      : (Attr *)S.mergeDLLImportAttr(D, A.getRange(), Index);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
@@ -4071,10 +4077,8 @@
     handleX86ForceAlignArgPointerAttr(S, D, Attr);
     break;
   case AttributeList::AT_DLLExport:
-    handleDLLExportAttr(S, D, Attr);
-    break;
   case AttributeList::AT_DLLImport:
-    handleDLLImportAttr(S, D, Attr);
+    handleDLLAttr(S, D, Attr);
     break;
   case AttributeList::AT_Mips16:
     handleSimpleAttribute<Mips16Attr>(S, D, Attr);
@@ -4854,7 +4858,8 @@
                           StringRef Message,
                           SourceLocation Loc,
                           const ObjCInterfaceDecl *UnknownObjCClass,
-                          const ObjCPropertyDecl *ObjCProperty) {
+                          const ObjCPropertyDecl *ObjCProperty,
+                          bool ObjCPropertyAccess) {
 
   // Diagnostics for deprecated or unavailable.
   unsigned diag, diag_message, diag_fwdclass_message;
@@ -4870,7 +4875,8 @@
     case DelayedDiagnostic::Deprecation:
       if (isDeclDeprecated(Ctx))
         return;
-      diag = diag::warn_deprecated;
+      diag = !ObjCPropertyAccess ? diag::warn_deprecated
+                                 : diag::warn_property_method_deprecated;
       diag_message = diag::warn_deprecated_message;
       diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
       property_note_select = /* deprecated */ 0;
@@ -4880,7 +4886,8 @@
     case DelayedDiagnostic::Unavailable:
       if (isDeclUnavailable(Ctx))
         return;
-      diag = diag::err_unavailable;
+      diag = !ObjCPropertyAccess ? diag::err_unavailable
+                                 : diag::err_property_method_unavailable;
       diag_message = diag::err_unavailable_message;
       diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
       property_note_select = /* unavailable */ 1;
@@ -4921,20 +4928,22 @@
                             DD.getDeprecationMessage(),
                             DD.Loc,
                             DD.getUnknownObjCClass(),
-                            DD.getObjCProperty());
+                            DD.getObjCProperty(), false);
 }
 
 void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,
                                    NamedDecl *D, StringRef Message,
                                    SourceLocation Loc,
                                    const ObjCInterfaceDecl *UnknownObjCClass,
-                                   const ObjCPropertyDecl  *ObjCProperty) {
+                                   const ObjCPropertyDecl  *ObjCProperty,
+                                   bool ObjCPropertyAccess) {
   // Delay if we're currently parsing a declaration.
   if (DelayedDiagnostics.shouldDelayDiagnostics()) {
     DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(AD, Loc, D,
                                                                UnknownObjCClass,
                                                                ObjCProperty,
-                                                               Message));
+                                                               Message,
+                                                               ObjCPropertyAccess));
     return;
   }
 
@@ -4950,5 +4959,5 @@
   }
 
   DoEmitAvailabilityWarning(*this, K, Ctx, D, Message, Loc,
-                            UnknownObjCClass, ObjCProperty);
+                            UnknownObjCClass, ObjCProperty, ObjCPropertyAccess);
 }
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 2f9f982..99eedf3 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -268,7 +268,7 @@
   ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Arg);
   if (Result.isInvalid())
     return true;
-  Arg = Result.takeAs<Expr>();
+  Arg = Result.getAs<Expr>();
 
   CheckCompletedExpr(Arg, EqualLoc);
   Arg = MaybeCreateExprWithCleanups(Arg);
@@ -1296,6 +1296,57 @@
   return false;
 }
 
+/// \brief Perform propagation of DLL attributes from a derived class to a
+/// templated base class for MS compatibility.
+static void propagateDLLAttrToBaseClassTemplate(
+    Sema &S, CXXRecordDecl *Class, Attr *ClassAttr,
+    ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) {
+  if (getDLLAttr(
+          BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) {
+    // If the base class template has a DLL attribute, don't try to change it.
+    return;
+  }
+
+  if (BaseTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
+    // If the base class is not already specialized, we can do the propagation.
+    auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
+    NewAttr->setInherited(true);
+    BaseTemplateSpec->addAttr(NewAttr);
+    return;
+  }
+
+  bool DifferentAttribute = false;
+  if (Attr *SpecializationAttr = getDLLAttr(BaseTemplateSpec)) {
+    if (!SpecializationAttr->isInherited()) {
+      // The template has previously been specialized or instantiated with an
+      // explicit attribute. We should not try to change it.
+      return;
+    }
+    if (SpecializationAttr->getKind() == ClassAttr->getKind()) {
+      // The specialization already has the right attribute.
+      return;
+    }
+    DifferentAttribute = true;
+  }
+
+  // The template was previously instantiated or explicitly specialized without
+  // a dll attribute, or the template was previously instantiated with a
+  // different inherited attribute. It's too late for us to change the
+  // attribute, so warn that this is unsupported.
+  S.Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class)
+      << BaseTemplateSpec->isExplicitSpecialization() << DifferentAttribute;
+  S.Diag(ClassAttr->getLocation(), diag::note_attribute);
+  if (BaseTemplateSpec->isExplicitSpecialization()) {
+    S.Diag(BaseTemplateSpec->getLocation(),
+           diag::note_template_class_explicit_specialization_was_here)
+        << BaseTemplateSpec;
+  } else {
+    S.Diag(BaseTemplateSpec->getPointOfInstantiation(),
+           diag::note_template_class_instantiation_was_here)
+        << BaseTemplateSpec;
+  }
+}
+
 /// \brief Check the validity of a C++ base class specifier.
 ///
 /// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics
@@ -1362,6 +1413,17 @@
     return nullptr;
   }
 
+  // For the MS ABI, propagate DLL attributes to base class templates.
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+    if (Attr *ClassAttr = getDLLAttr(Class)) {
+      if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
+              BaseType->getAsCXXRecordDecl())) {
+        propagateDLLAttrToBaseClassTemplate(*this, Class, ClassAttr,
+                                            BaseTemplate, BaseLoc);
+      }
+    }
+  }
+
   // C++ [class.derived]p2:
   //   The class-name in a base-specifier shall not be an incompletely
   //   defined class.
@@ -1398,8 +1460,8 @@
     Diag(BaseLoc, diag::err_class_marked_final_used_as_base)
       << CXXBaseDecl->getDeclName()
       << FA->isSpelledAsSealed();
-    Diag(CXXBaseDecl->getLocation(), diag::note_previous_decl)
-      << CXXBaseDecl->getDeclName();
+    Diag(CXXBaseDecl->getLocation(), diag::note_entity_declared_at)
+        << CXXBaseDecl->getDeclName() << FA->getRange();
     return nullptr;
   }
 
@@ -1431,6 +1493,9 @@
   if (!Class)
     return true;
 
+  // We haven't yet attached the base specifiers.
+  Class->setIsParsingBaseSpecifiers();
+
   // We do not support any C++11 attributes on base-specifiers yet.
   // Diagnose any attributes we see.
   if (!Attributes.empty()) {
@@ -2116,9 +2181,7 @@
     FieldDecl *FD = cast<FieldDecl>(Member);
     FieldCollector->Add(FD);
 
-    if (Diags.getDiagnosticLevel(diag::warn_unused_private_field,
-                                 FD->getLocation())
-          != DiagnosticsEngine::Ignored) {
+    if (!Diags.isIgnored(diag::warn_unused_private_field, FD->getLocation())) {
       // Remember all explicit private FieldDecls that have a name, no side
       // effects and are not part of a dependent type declaration.
       if (!FD->isImplicit() && FD->getDeclName() &&
@@ -2306,9 +2369,8 @@
   static void DiagnoseUninitializedFields(
       Sema &SemaRef, const CXXConstructorDecl *Constructor) {
 
-    if (SemaRef.getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit,
-                                                    Constructor->getLocation())
-        == DiagnosticsEngine::Ignored) {
+    if (SemaRef.getDiagnostics().isIgnored(diag::warn_field_is_uninit,
+                                           Constructor->getLocation())) {
       return;
     }
 
@@ -2392,13 +2454,13 @@
   // C++11 [class.base.init]p7:
   //   The initialization of each base and member constitutes a
   //   full-expression.
-  Init = ActOnFinishFullExpr(Init.take(), InitLoc);
+  Init = ActOnFinishFullExpr(Init.get(), InitLoc);
   if (Init.isInvalid()) {
     FD->setInvalidDecl();
     return;
   }
 
-  InitExpr = Init.release();
+  InitExpr = Init.get();
 
   FD->setInClassInitializer(InitExpr);
 }
@@ -2833,10 +2895,10 @@
   // initializer. However, deconstructing the ASTs is a dicey process,
   // and this approach is far more likely to get the corner cases right.
   if (CurContext->isDependentContext())
-    DelegationInit = Owned(Init);
+    DelegationInit = Init;
 
   return new (Context) CXXCtorInitializer(Context, TInfo, InitRange.getBegin(), 
-                                          DelegationInit.takeAs<Expr>(),
+                                          DelegationInit.getAs<Expr>(),
                                           InitRange.getEnd());
 }
 
@@ -2962,12 +3024,12 @@
   // initializer. However, deconstructing the ASTs is a dicey process,
   // and this approach is far more likely to get the corner cases right.
   if (CurContext->isDependentContext())
-    BaseInit = Owned(Init);
+    BaseInit = Init;
 
   return new (Context) CXXCtorInitializer(Context, BaseTInfo,
                                           BaseSpec->isVirtual(),
                                           InitRange.getBegin(),
-                                          BaseInit.takeAs<Expr>(),
+                                          BaseInit.getAs<Expr>(),
                                           InitRange.getEnd(), EllipsisLoc);
 }
 
@@ -2982,7 +3044,7 @@
 
   return SemaRef.BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E,
                                    SourceRange(ExprLoc, ExprLoc),
-                                   E->getSourceRange()).take();
+                                   E->getSourceRange()).get();
 }
 
 /// ImplicitInitializerKind - How an implicit base or member initializer should
@@ -3024,7 +3086,7 @@
                                      VK_LValue, SourceLocation());
         if (ArgExpr.isInvalid())
           return true;
-        Args.push_back(CastForMoving(SemaRef, ArgExpr.take(), PD->getType()));
+        Args.push_back(CastForMoving(SemaRef, ArgExpr.get(), PD->getType()));
       }
 
       InitializationKind InitKind = InitializationKind::CreateDirect(
@@ -3071,7 +3133,7 @@
     CopyCtorArg = SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
                                             CK_UncheckedDerivedToBase,
                                             Moving ? VK_XValue : VK_LValue,
-                                            &BasePath).take();
+                                            &BasePath).get();
 
     InitializationKind InitKind
       = InitializationKind::CreateDirect(Constructor->getLocation(),
@@ -3092,7 +3154,7 @@
                                                         SourceLocation()),
                                              BaseSpec->isVirtual(),
                                              SourceLocation(),
-                                             BaseInit.takeAs<Expr>(),
+                                             BaseInit.getAs<Expr>(),
                                              SourceLocation(),
                                              SourceLocation());
 
@@ -3157,7 +3219,7 @@
     //   - if a member m has rvalue reference type T&&, it is direct-initialized
     //     with static_cast<T&&>(x.m);
     if (RefersToRValueRef(CtorArg.get())) {
-      CtorArg = CastForMoving(SemaRef, CtorArg.take());
+      CtorArg = CastForMoving(SemaRef, CtorArg.get());
     }
 
     // When the field we are copying is an array, create index variables for 
@@ -3191,13 +3253,13 @@
         = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
       assert(!IterationVarRef.isInvalid() &&
              "Reference to invented variable cannot fail!");
-      IterationVarRef = SemaRef.DefaultLvalueConversion(IterationVarRef.take());
+      IterationVarRef = SemaRef.DefaultLvalueConversion(IterationVarRef.get());
       assert(!IterationVarRef.isInvalid() &&
              "Conversion of invented variable cannot fail!");
 
       // Subscript the array with this iteration variable.
-      CtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CtorArg.take(), Loc,
-                                                        IterationVarRef.take(),
+      CtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CtorArg.get(), Loc,
+                                                        IterationVarRef.get(),
                                                         Loc);
       if (CtorArg.isInvalid())
         return true;
@@ -3207,7 +3269,7 @@
 
     // The array subscript expression is an lvalue, which is wrong for moving.
     if (Moving && InitializingArray)
-      CtorArg = CastForMoving(SemaRef, CtorArg.take());
+      CtorArg = CastForMoving(SemaRef, CtorArg.get());
 
     // Construct the entity that we will be initializing. For an array, this
     // will be first element in the array, which may require several levels
@@ -3227,7 +3289,7 @@
     InitializationKind InitKind =
       InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation());
     
-    Expr *CtorArgE = CtorArg.takeAs<Expr>();
+    Expr *CtorArgE = CtorArg.getAs<Expr>();
     InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind, CtorArgE);
     
     ExprResult MemberInit
@@ -3243,11 +3305,11 @@
       CXXMemberInit
         = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect, 
                                                    Loc, Loc, 
-                                                   MemberInit.takeAs<Expr>(), 
+                                                   MemberInit.getAs<Expr>(), 
                                                    Loc);
     } else
       CXXMemberInit = CXXCtorInitializer::Create(SemaRef.Context, Field, Loc, 
-                                                 Loc, MemberInit.takeAs<Expr>(), 
+                                                 Loc, MemberInit.getAs<Expr>(), 
                                                  Loc,
                                                  IndexVariables.data(),
                                                  IndexVariables.size());
@@ -3731,9 +3793,8 @@
   bool ShouldCheckOrder = false;
   for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) {
     CXXCtorInitializer *Init = Inits[InitIndex];
-    if (SemaRef.Diags.getDiagnosticLevel(diag::warn_initializer_out_of_order,
-                                         Init->getSourceLocation())
-          != DiagnosticsEngine::Ignored) {
+    if (!SemaRef.Diags.isIgnored(diag::warn_initializer_out_of_order,
+                                 Init->getSourceLocation())) {
       ShouldCheckOrder = true;
       break;
     }
@@ -4348,6 +4409,77 @@
   }
 }
 
+/// \brief Check class-level dllimport/dllexport attribute.
+static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
+  Attr *ClassAttr = getDLLAttr(Class);
+  if (!ClassAttr)
+    return;
+
+  bool ClassExported = ClassAttr->getKind() == attr::DLLExport;
+
+  // Force declaration of implicit members so they can inherit the attribute.
+  S.ForceDeclarationOfImplicitMembers(Class);
+
+  // FIXME: MSVC's docs say all bases must be exportable, but this doesn't
+  // seem to be true in practice?
+
+  for (Decl *Member : Class->decls()) {
+    VarDecl *VD = dyn_cast<VarDecl>(Member);
+    CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member);
+
+    // Only methods and static fields inherit the attributes.
+    if (!VD && !MD)
+      continue;
+
+    // Don't process deleted methods.
+    if (MD && MD->isDeleted())
+      continue;
+
+    if (MD && MD->isMoveAssignmentOperator() && !ClassExported &&
+        MD->isInlined()) {
+      // Current MSVC versions don't export the move assignment operators, so
+      // don't attempt to import them if we have a definition.
+      continue;
+    }
+
+    if (InheritableAttr *MemberAttr = getDLLAttr(Member)) {
+      if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+          !MemberAttr->isInherited() && !ClassAttr->isInherited()) {
+        S.Diag(MemberAttr->getLocation(),
+               diag::err_attribute_dll_member_of_dll_class)
+            << MemberAttr << ClassAttr;
+        S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute);
+        Member->setInvalidDecl();
+        continue;
+      }
+    } else {
+      auto *NewAttr =
+          cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
+      NewAttr->setInherited(true);
+      Member->addAttr(NewAttr);
+    }
+
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
+      if (ClassExported) {
+        if (MD->isUserProvided()) {
+          // Instantiate non-default methods.
+          S.MarkFunctionReferenced(Class->getLocation(), MD);
+        } else if (!MD->isTrivial() || MD->isExplicitlyDefaulted() ||
+                   MD->isCopyAssignmentOperator() ||
+                   MD->isMoveAssignmentOperator()) {
+          // Instantiate non-trivial or explicitly defaulted methods, and the
+          // copy assignment / move assignment operators.
+          S.MarkFunctionReferenced(Class->getLocation(), MD);
+          // Resolve its exception specification; CodeGen needs it.
+          auto *FPT = MD->getType()->getAs<FunctionProtoType>();
+          S.ResolveExceptionSpec(Class->getLocation(), FPT);
+          S.ActOnFinishInlineMethodDef(MD);
+        }
+      }
+    }
+  }
+}
+
 /// \brief Perform semantic checks on a class definition that has been
 /// completing, introducing implicitly-declared members, checking for
 /// abstract types, etc.
@@ -4512,6 +4644,8 @@
   //   instantiated (e.g. meta-functions). This doesn't apply to classes that
   //   have inheriting constructors.
   DeclareInheritingConstructors(Record);
+
+  checkDLLAttribute(*this, Record);
 }
 
 /// Look up the special member function that would be called by a special
@@ -5881,8 +6015,7 @@
   if (MD->isInvalidDecl())
     return;
 
-  if (Diags.getDiagnosticLevel(diag::warn_overloaded_virtual,
-                               MD->getLocation()) == DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_overloaded_virtual, MD->getLocation()))
     return;
 
   SmallVector<CXXMethodDecl *, 8> OverloadedMethods;
@@ -6146,6 +6279,15 @@
     SC = SC_None;
   }
 
+  if (unsigned TypeQuals = D.getDeclSpec().getTypeQualifiers()) {
+    diagnoseIgnoredQualifiers(
+        diag::err_constructor_return_type, TypeQuals, SourceLocation(),
+        D.getDeclSpec().getConstSpecLoc(), D.getDeclSpec().getVolatileSpecLoc(),
+        D.getDeclSpec().getRestrictSpecLoc(),
+        D.getDeclSpec().getAtomicSpecLoc());
+    D.setInvalidType();
+  }
+
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
   if (FTI.TypeQuals != 0) {
     if (FTI.TypeQuals & Qualifiers::Const)
@@ -6293,7 +6435,7 @@
     
     SC = SC_None;
   }
-  if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
+  if (!D.isInvalidType()) {
     // Destructors don't have return types, but the parser will
     // happily parse something like:
     //
@@ -6302,9 +6444,19 @@
     //   };
     //
     // The return type will be eliminated later.
-    Diag(D.getIdentifierLoc(), diag::err_destructor_return_type)
-      << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
-      << SourceRange(D.getIdentifierLoc());
+    if (D.getDeclSpec().hasTypeSpecifier())
+      Diag(D.getIdentifierLoc(), diag::err_destructor_return_type)
+        << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
+        << SourceRange(D.getIdentifierLoc());
+    else if (unsigned TypeQuals = D.getDeclSpec().getTypeQualifiers()) {
+      diagnoseIgnoredQualifiers(diag::err_destructor_return_type, TypeQuals,
+                                SourceLocation(),
+                                D.getDeclSpec().getConstSpecLoc(),
+                                D.getDeclSpec().getVolatileSpecLoc(),
+                                D.getDeclSpec().getRestrictSpecLoc(),
+                                D.getDeclSpec().getAtomicSpecLoc());
+      D.setInvalidType();
+    }
   }
 
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
@@ -8333,7 +8485,9 @@
     return;
   }
 
-  SourceLocation Loc = Constructor->getLocation();
+  SourceLocation Loc = Constructor->getLocEnd().isValid()
+                           ? Constructor->getLocEnd()
+                           : Constructor->getLocation();
   Constructor->setBody(new (Context) CompoundStmt(Loc));
 
   Constructor->markUsed(Context);
@@ -8795,7 +8949,9 @@
     return;
   }
 
-  SourceLocation Loc = Destructor->getLocation();
+  SourceLocation Loc = Destructor->getLocEnd().isValid()
+                           ? Destructor->getLocEnd()
+                           : Destructor->getLocation();
   Destructor->setBody(new (Context) CompoundStmt(Loc));
   Destructor->markUsed(Context);
   MarkVTableUsed(CurrentLocation, ClassDecl);
@@ -8874,7 +9030,7 @@
 
 public:
   virtual Expr *build(Sema &S, SourceLocation Loc) const override {
-    return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).take());
+    return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).get());
   }
 
   RefBuilder(VarDecl *Var, QualType VarType)
@@ -8884,7 +9040,7 @@
 class ThisBuilder: public ExprBuilder {
 public:
   virtual Expr *build(Sema &S, SourceLocation Loc) const override {
-    return assertNotNull(S.ActOnCXXThis(Loc).takeAs<Expr>());
+    return assertNotNull(S.ActOnCXXThis(Loc).getAs<Expr>());
   }
 };
 
@@ -8898,7 +9054,7 @@
   virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(S.ImpCastExprToType(Builder.build(S, Loc), Type,
                                              CK_UncheckedDerivedToBase, Kind,
-                                             &Path).take());
+                                             &Path).get());
   }
 
   CastBuilder(const ExprBuilder &Builder, QualType Type, ExprValueKind Kind,
@@ -8912,7 +9068,7 @@
 public:
   virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(
-        S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).take());
+        S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).get());
   }
 
   DerefBuilder(const ExprBuilder &Builder) : Builder(Builder) {}
@@ -8929,7 +9085,7 @@
   virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(S.BuildMemberReferenceExpr(
         Builder.build(S, Loc), Type, Loc, IsArrow, SS, SourceLocation(),
-        nullptr, MemberLookup, nullptr).take());
+        nullptr, MemberLookup, nullptr).get());
   }
 
   MemberBuilder(const ExprBuilder &Builder, QualType Type, bool IsArrow,
@@ -8955,7 +9111,7 @@
 public:
   virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(
-        S.DefaultLvalueConversion(Builder.build(S, Loc)).take());
+        S.DefaultLvalueConversion(Builder.build(S, Loc)).get());
   }
 
   LvalueConvBuilder(const ExprBuilder &Builder) : Builder(Builder) {}
@@ -8968,7 +9124,7 @@
 public:
   virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(S.CreateBuiltinArraySubscriptExpr(
-        Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).take());
+        Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).get());
   }
 
   SubscriptBuilder(const ExprBuilder &Base, const ExprBuilder &Index)
@@ -9026,11 +9182,11 @@
   Expr *CallArgs[] = {
     To, From, IntegerLiteral::Create(S.Context, Size, SizeType, Loc)
   };
-  ExprResult Call = S.ActOnCallExpr(/*Scope=*/nullptr, MemCpyRef.take(),
+  ExprResult Call = S.ActOnCallExpr(/*Scope=*/nullptr, MemCpyRef.get(),
                                     Loc, CallArgs, Loc);
 
   assert(!Call.isInvalid() && "Call to __builtin_memcpy cannot fail!");
-  return S.Owned(Call.takeAs<Stmt>());
+  return Call.getAs<Stmt>();
 }
 
 /// \brief Builds a statement that copies/moves the given entity from \p From to
@@ -9148,7 +9304,7 @@
 
     Expr *FromInst = From.build(S, Loc);
     ExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/nullptr,
-                                                  OpEqualRef.takeAs<Expr>(),
+                                                  OpEqualRef.getAs<Expr>(),
                                                   Loc, FromInst, Loc);
     if (Call.isInvalid())
       return StmtError();
@@ -9247,7 +9403,7 @@
   return S.ActOnForStmt(Loc, Loc, InitStmt, 
                         S.MakeFullExpr(Comparison),
                         nullptr, S.MakeFullDiscardedValueExpr(Increment),
-                        Loc, Copy.take());
+                        Loc, Copy.get());
 }
 
 static StmtResult
@@ -9495,8 +9651,10 @@
   }
   
   // Our location for everything implicitly-generated.
-  SourceLocation Loc = CopyAssignOperator->getLocation();
-  
+  SourceLocation Loc = CopyAssignOperator->getLocEnd().isValid()
+                           ? CopyAssignOperator->getLocEnd()
+                           : CopyAssignOperator->getLocation();
+
   // Builds a DeclRefExpr for the "other" object.
   RefBuilder OtherRef(Other, OtherRefType);
 
@@ -9542,7 +9700,7 @@
     }
     
     // Success! Record the copy.
-    Statements.push_back(Copy.takeAs<Expr>());
+    Statements.push_back(Copy.getAs<Expr>());
   }
   
   // Assign non-static members.
@@ -9613,7 +9771,7 @@
     }
     
     // Success! Record the copy.
-    Statements.push_back(Copy.takeAs<Stmt>());
+    Statements.push_back(Copy.getAs<Stmt>());
   }
 
   if (!Invalid) {
@@ -9624,7 +9782,7 @@
     if (Return.isInvalid())
       Invalid = true;
     else {
-      Statements.push_back(Return.takeAs<Stmt>());
+      Statements.push_back(Return.getAs<Stmt>());
 
       if (Trap.hasErrorOccurred()) {
         Diag(CurrentLocation, diag::note_member_synthesized_at) 
@@ -9646,7 +9804,7 @@
                              /*isStmtExpr=*/false);
     assert(!Body.isInvalid() && "Compound statement creation cannot fail");
   }
-  CopyAssignOperator->setBody(Body.takeAs<Stmt>());
+  CopyAssignOperator->setBody(Body.getAs<Stmt>());
 
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(CopyAssignOperator);
@@ -9900,7 +10058,9 @@
          "Bad argument type of defaulted move assignment");
 
   // Our location for everything implicitly-generated.
-  SourceLocation Loc = MoveAssignOperator->getLocation();
+  SourceLocation Loc = MoveAssignOperator->getLocEnd().isValid()
+                           ? MoveAssignOperator->getLocEnd()
+                           : MoveAssignOperator->getLocation();
 
   // Builds a reference to the "other" object.
   RefBuilder OtherRef(Other, OtherRefType);
@@ -9958,7 +10118,7 @@
     }
 
     // Success! Record the move.
-    Statements.push_back(Move.takeAs<Expr>());
+    Statements.push_back(Move.getAs<Expr>());
   }
 
   // Assign non-static members.
@@ -10032,18 +10192,19 @@
     }
 
     // Success! Record the copy.
-    Statements.push_back(Move.takeAs<Stmt>());
+    Statements.push_back(Move.getAs<Stmt>());
   }
 
   if (!Invalid) {
     // Add a "return *this;"
-    ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
-    
+    ExprResult ThisObj =
+        CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
+
     StmtResult Return = BuildReturnStmt(Loc, ThisObj.get());
     if (Return.isInvalid())
       Invalid = true;
     else {
-      Statements.push_back(Return.takeAs<Stmt>());
+      Statements.push_back(Return.getAs<Stmt>());
 
       if (Trap.hasErrorOccurred()) {
         Diag(CurrentLocation, diag::note_member_synthesized_at) 
@@ -10065,7 +10226,7 @@
                              /*isStmtExpr=*/false);
     assert(!Body.isInvalid() && "Compound statement creation cannot fail");
   }
-  MoveAssignOperator->setBody(Body.takeAs<Stmt>());
+  MoveAssignOperator->setBody(Body.getAs<Stmt>());
 
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(MoveAssignOperator);
@@ -10214,10 +10375,12 @@
       << CXXCopyConstructor << Context.getTagDeclType(ClassDecl);
     CopyConstructor->setInvalidDecl();
   }  else {
+    SourceLocation Loc = CopyConstructor->getLocEnd().isValid()
+                             ? CopyConstructor->getLocEnd()
+                             : CopyConstructor->getLocation();
     Sema::CompoundScopeRAII CompoundScope(*this);
-    CopyConstructor->setBody(ActOnCompoundStmt(
-        CopyConstructor->getLocation(), CopyConstructor->getLocation(), None,
-        /*isStmtExpr=*/ false).takeAs<Stmt>());
+    CopyConstructor->setBody(
+        ActOnCompoundStmt(Loc, Loc, None, /*isStmtExpr=*/false).getAs<Stmt>());
   }
 
   CopyConstructor->markUsed(Context);
@@ -10370,10 +10533,12 @@
       << CXXMoveConstructor << Context.getTagDeclType(ClassDecl);
     MoveConstructor->setInvalidDecl();
   }  else {
+    SourceLocation Loc = MoveConstructor->getLocEnd().isValid()
+                             ? MoveConstructor->getLocEnd()
+                             : MoveConstructor->getLocation();
     Sema::CompoundScopeRAII CompoundScope(*this);
     MoveConstructor->setBody(ActOnCompoundStmt(
-        MoveConstructor->getLocation(), MoveConstructor->getLocation(), None,
-        /*isStmtExpr=*/ false).takeAs<Stmt>());
+        Loc, Loc, None, /*isStmtExpr=*/ false).getAs<Stmt>());
   }
 
   MoveConstructor->markUsed(Context);
@@ -10406,8 +10571,7 @@
     DeducedTemplateArgs = Conv->getTemplateSpecializationArgs();
     void *InsertPos = nullptr;
     FunctionDecl *CallOpSpec = CallOpTemplate->findSpecialization(
-                                                DeducedTemplateArgs->data(), 
-                                                DeducedTemplateArgs->size(), 
+                                                DeducedTemplateArgs->asArray(),
                                                 InsertPos);
     assert(CallOpSpec && 
           "Conversion operator must have a corresponding call operator");
@@ -10433,8 +10597,7 @@
                           Invoker->getDescribedFunctionTemplate();
     void *InsertPos = nullptr;
     FunctionDecl *InvokeSpec = InvokeTemplate->findSpecialization(
-                                                DeducedTemplateArgs->data(), 
-                                                DeducedTemplateArgs->size(), 
+                                                DeducedTemplateArgs->asArray(),
                                                 InsertPos);
     assert(InvokeSpec && 
       "Must have a corresponding static invoker specialization");
@@ -10442,9 +10605,9 @@
   }
   // Construct the body of the conversion function { return __invoke; }.
   Expr *FunctionRef = BuildDeclRefExpr(Invoker, Invoker->getType(),
-                                        VK_LValue, Conv->getLocation()).take();
+                                        VK_LValue, Conv->getLocation()).get();
    assert(FunctionRef && "Can't refer to __invoke function?");
-   Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).take();
+   Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).get();
    Conv->setBody(new (Context) CompoundStmt(Context, Return,
                                             Conv->getLocation(),
                                             Conv->getLocation()));
@@ -10478,8 +10641,8 @@
   DiagnosticErrorTrap Trap(Diags);
   
   // Copy-initialize the lambda object as needed to capture it.
-  Expr *This = ActOnCXXThis(CurrentLocation).take();
-  Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).take();
+  Expr *This = ActOnCXXThis(CurrentLocation).get();
+  Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).get();
   
   ExprResult BuildBlock = BuildBlockForLambdaConversion(CurrentLocation,
                                                         Conv->getLocation(),
@@ -10510,7 +10673,7 @@
   }
 
   // Set the body of the conversion function.
-  Stmt *ReturnS = Return.take();
+  Stmt *ReturnS = Return.get();
   Conv->setBody(new (Context) CompoundStmt(Context, ReturnS,
                                            Conv->getLocation(), 
                                            Conv->getLocation()));
@@ -10585,12 +10748,11 @@
                             unsigned ConstructKind,
                             SourceRange ParenRange) {
   MarkFunctionReferenced(ConstructLoc, Constructor);
-  return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
-                                        Constructor, Elidable, ExprArgs,
-                                        HadMultipleCandidates,
-                                        IsListInitialization, RequiresZeroInit,
-              static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
-                                        ParenRange));
+  return CXXConstructExpr::Create(
+      Context, DeclInitType, ConstructLoc, Constructor, Elidable, ExprArgs,
+      HadMultipleCandidates, IsListInitialization, RequiresZeroInit,
+      static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
+      ParenRange);
 }
 
 void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
@@ -11242,7 +11404,7 @@
       else {
         // If the constructor used was non-trivial, set this as the
         // "initializer".
-        CXXConstructExpr *construct = result.takeAs<CXXConstructExpr>();
+        CXXConstructExpr *construct = result.getAs<CXXConstructExpr>();
         if (!construct->getConstructor()->isTrivial()) {
           Expr *init = MaybeCreateExprWithCleanups(construct);
           ExDecl->setInit(init);
@@ -11279,13 +11441,17 @@
                                              LookupOrdinaryName,
                                              ForRedeclaration)) {
     // The scope should be freshly made just for us. There is just no way
-    // it contains any previous declaration.
+    // it contains any previous declaration, except for function parameters in
+    // a function-try-block's catch statement.
     assert(!S->isDeclScope(PrevDecl));
-    if (PrevDecl->isTemplateParameter()) {
+    if (isDeclInScope(PrevDecl, CurContext, S)) {
+      Diag(D.getIdentifierLoc(), diag::err_redefinition)
+        << D.getIdentifier();
+      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      Invalid = true;
+    } else if (PrevDecl->isTemplateParameter())
       // Maybe we will complain about the shadowed template parameter.
       DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
-      PrevDecl = nullptr;
-    }
   }
 
   if (D.getCXXScopeSpec().isSet() && !Invalid) {
@@ -11315,7 +11481,8 @@
                                          Expr *AssertExpr,
                                          Expr *AssertMessageExpr,
                                          SourceLocation RParenLoc) {
-  StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr);
+  StringLiteral *AssertMessage =
+      AssertMessageExpr ? cast<StringLiteral>(AssertMessageExpr) : nullptr;
 
   if (DiagnoseUnexpandedParameterPack(AssertExpr, UPPC_StaticAssertExpression))
     return nullptr;
@@ -11329,6 +11496,7 @@
                                          StringLiteral *AssertMessage,
                                          SourceLocation RParenLoc,
                                          bool Failed) {
+  assert(AssertExpr != nullptr && "Expected non-null condition");
   if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent() &&
       !Failed) {
     // In a static_assert-declaration, the constant-expression shall be a
@@ -11346,9 +11514,10 @@
     if (!Failed && !Cond) {
       SmallString<256> MsgBuffer;
       llvm::raw_svector_ostream Msg(MsgBuffer);
-      AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
+      if (AssertMessage)
+        AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
       Diag(StaticAssertLoc, diag::err_static_assert_failed)
-        << Msg.str() << AssertExpr->getSourceRange();
+        << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
       Failed = true;
     }
   }
@@ -11462,7 +11631,7 @@
                                 TemplateParams, AS_public,
                                 /*ModulePrivateLoc=*/SourceLocation(),
                                 TempParamLists.size() - 1,
-                                TempParamLists.data()).take();
+                                TempParamLists.data()).get();
     } else {
       // The "template<>" header is extraneous.
       Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
@@ -11972,6 +12141,12 @@
     Fn = Fn->getCanonicalDecl();
   }
 
+  // dllimport/dllexport cannot be deleted.
+  if (const InheritableAttr *DLLAttr = getDLLAttr(Fn)) {
+    Diag(Fn->getLocation(), diag::err_attribute_dll_deleted) << DLLAttr;
+    Fn->setInvalidDecl();
+  }
+
   if (Fn->isDeleted())
     return;
 
@@ -12148,8 +12323,10 @@
   if (NewClassTy.isNull()) {
     Diag(New->getLocation(),
          diag::err_different_return_type_for_overriding_virtual_function)
-      << New->getDeclName() << NewTy << OldTy;
-    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+        << New->getDeclName() << NewTy << OldTy
+        << New->getReturnTypeSourceRange();
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+        << Old->getReturnTypeSourceRange();
 
     return true;
   }
@@ -12169,25 +12346,27 @@
   if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
     // Check if the new class derives from the old class.
     if (!IsDerivedFrom(NewClassTy, OldClassTy)) {
-      Diag(New->getLocation(),
-           diag::err_covariant_return_not_derived)
-      << New->getDeclName() << NewTy << OldTy;
-      Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+      Diag(New->getLocation(), diag::err_covariant_return_not_derived)
+          << New->getDeclName() << NewTy << OldTy
+          << New->getReturnTypeSourceRange();
+      Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+          << Old->getReturnTypeSourceRange();
       return true;
     }
 
     // Check if we the conversion from derived to base is valid.
-    if (CheckDerivedToBaseConversion(NewClassTy, OldClassTy,
-                    diag::err_covariant_return_inaccessible_base,
-                    diag::err_covariant_return_ambiguous_derived_to_base_conv,
-                    // FIXME: Should this point to the return type?
-                    New->getLocation(), SourceRange(), New->getDeclName(),
-                    nullptr)) {
+    if (CheckDerivedToBaseConversion(
+            NewClassTy, OldClassTy,
+            diag::err_covariant_return_inaccessible_base,
+            diag::err_covariant_return_ambiguous_derived_to_base_conv,
+            New->getLocation(), New->getReturnTypeSourceRange(),
+            New->getDeclName(), nullptr)) {
       // FIXME: this note won't trigger for delayed access control
       // diagnostics, and it's impossible to get an undelayed error
       // here from access control during the original parse because
       // the ParsingDeclSpec/ParsingDeclarator are still in scope.
-      Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+      Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+          << Old->getReturnTypeSourceRange();
       return true;
     }
   }
@@ -12196,8 +12375,10 @@
   if (NewTy.getLocalCVRQualifiers() != OldTy.getLocalCVRQualifiers()) {
     Diag(New->getLocation(),
          diag::err_covariant_return_type_different_qualifications)
-    << New->getDeclName() << NewTy << OldTy;
-    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+        << New->getDeclName() << NewTy << OldTy
+        << New->getReturnTypeSourceRange();
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+        << Old->getReturnTypeSourceRange();
     return true;
   };
 
@@ -12206,8 +12387,10 @@
   if (NewClassTy.isMoreQualifiedThan(OldClassTy)) {
     Diag(New->getLocation(),
          diag::err_covariant_return_type_class_type_more_qualified)
-    << New->getDeclName() << NewTy << OldTy;
-    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+        << New->getDeclName() << NewTy << OldTy
+        << New->getReturnTypeSourceRange();
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+        << Old->getReturnTypeSourceRange();
     return true;
   };
 
@@ -12364,7 +12547,9 @@
         Class->hasUserDeclaredDestructor() &&
         !Class->getDestructor()->isDefined() &&
         !Class->getDestructor()->isDeleted()) {
-      CheckDestructor(Class->getDestructor());
+      CXXDestructorDecl *DD = Class->getDestructor();
+      ContextRAII SavedContext(*this, DD);
+      CheckDestructor(DD);
     }
   }
 
@@ -12540,7 +12725,7 @@
       Member =
         new (Context) CXXCtorInitializer(Context, Field, SourceLocation(),
                                          SourceLocation(),
-                                         MemberInit.takeAs<Expr>(),
+                                         MemberInit.getAs<Expr>(),
                                          SourceLocation());
       AllToInit.push_back(Member);
       
@@ -12823,7 +13008,7 @@
       if (!NoexceptExpr->isValueDependent())
         NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, nullptr,
                          diag::err_noexcept_needs_constant_expression,
-                         /*AllowFold*/ false).take();
+                         /*AllowFold*/ false).get();
       EPI.NoexceptExpr = NoexceptExpr;
     }
     return;
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index fc9fdb1..b5205b3 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1770,8 +1770,7 @@
               if (C || MethodInClass->isPropertyAccessor())
                 continue;
             unsigned DIAG = diag::warn_unimplemented_protocol_method;
-            if (S.Diags.getDiagnosticLevel(DIAG, ImpLoc)
-                != DiagnosticsEngine::Ignored) {
+            if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
               WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
                                   PDecl);
             }
@@ -1794,8 +1793,7 @@
         continue;
 
       unsigned DIAG = diag::warn_unimplemented_protocol_method;
-      if (S.Diags.getDiagnosticLevel(DIAG, ImpLoc) !=
-            DiagnosticsEngine::Ignored) {
+      if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
         WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
       }
     }
@@ -2349,10 +2347,8 @@
   // We support a warning which complains about *any* difference in
   // method signature.
   bool strictSelectorMatch =
-    (receiverIdOrClass && warn &&
-     (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl,
-                               R.getBegin())
-        != DiagnosticsEngine::Ignored));
+      receiverIdOrClass && warn &&
+      !Diags.isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin());
   if (strictSelectorMatch) {
     for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
       if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) {
@@ -3527,7 +3523,7 @@
   for (const auto *CurMethod : ImplD->instance_methods()) {
     unsigned DIAG = diag::warn_unused_property_backing_ivar;
     SourceLocation Loc = CurMethod->getLocation();
-    if (Diags.getDiagnosticLevel(DIAG, Loc) == DiagnosticsEngine::Ignored)
+    if (Diags.isIgnored(DIAG, Loc))
       continue;
 
     const ObjCPropertyDecl *PDecl;
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index 24d8222..6eccb9f 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -283,6 +283,7 @@
 
   case EST_ComputedNoexcept:
     OS << "noexcept(";
+    assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr");
     OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy());
     OS << ")";
     break;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a9f1197..67e839c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -83,9 +83,16 @@
 
 static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S,
                               NamedDecl *D, SourceLocation Loc,
-                              const ObjCInterfaceDecl *UnknownObjCClass) {
+                              const ObjCInterfaceDecl *UnknownObjCClass,
+                              bool ObjCPropertyAccess) {
   // See if this declaration is unavailable or deprecated.
   std::string Message;
+    
+  // Forward class declarations get their attributes from their definition.
+  if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
+    if (IDecl->getDefinition())
+      D = IDecl->getDefinition();
+  }
   AvailabilityResult Result = D->getAvailability(&Message);
   if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
     if (Result == AR_Available) {
@@ -113,13 +120,15 @@
     case AR_Deprecated:
       if (S.getCurContextAvailability() != AR_Deprecated)
         S.EmitAvailabilityWarning(Sema::AD_Deprecation,
-                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl);
+                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl,
+                                  ObjCPropertyAccess);
       break;
 
     case AR_Unavailable:
       if (S.getCurContextAvailability() != AR_Unavailable)
         S.EmitAvailabilityWarning(Sema::AD_Unavailable,
-                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl);
+                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl,
+                                  ObjCPropertyAccess);
       break;
 
     }
@@ -223,9 +232,8 @@
 
   S.MaybeSuggestAddingStaticToDecl(Current);
 
-  S.Diag(D->getCanonicalDecl()->getLocation(),
-         diag::note_internal_decl_declared_here)
-    << D;
+  S.Diag(D->getCanonicalDecl()->getLocation(), diag::note_entity_declared_at)
+      << D;
 }
 
 void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) {
@@ -252,7 +260,8 @@
 /// referenced), false otherwise.
 ///
 bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
-                             const ObjCInterfaceDecl *UnknownObjCClass) {
+                             const ObjCInterfaceDecl *UnknownObjCClass,
+                             bool ObjCPropertyAccess) {
   if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) {
     // If there were any diagnostics suppressed by template argument deduction,
     // emit them now.
@@ -297,7 +306,7 @@
         DeduceReturnType(FD, Loc))
       return true;
   }
-  DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass);
+  DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, ObjCPropertyAccess);
 
   DiagnoseUnusedOfDecl(*this, D, Loc);
 
@@ -426,7 +435,7 @@
   if (E->getType()->isPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
     if (result.isInvalid()) return ExprError();
-    E = result.take();
+    E = result.get();
   }
   
   QualType Ty = E->getType();
@@ -440,7 +449,7 @@
       return ExprError();
     }
     E = ImpCastExprToType(E, Context.getPointerType(Ty),
-                          CK_FunctionToPointerDecay).take();
+                          CK_FunctionToPointerDecay).get();
   } else if (Ty->isArrayType()) {
     // In C90 mode, arrays only promote to pointers if the array expression is
     // an lvalue.  The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
@@ -455,9 +464,9 @@
     //
     if (getLangOpts().C99 || getLangOpts().CPlusPlus || E->isLValue())
       E = ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
-                            CK_ArrayToPointerDecay).take();
+                            CK_ArrayToPointerDecay).get();
   }
-  return Owned(E);
+  return E;
 }
 
 static void CheckForNullPointerDereference(Sema &S, Expr *E) {
@@ -540,13 +549,13 @@
   if (E->getType()->isPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
     if (result.isInvalid()) return ExprError();
-    E = result.take();
+    E = result.get();
   }
   
   // C++ [conv.lval]p1:
   //   A glvalue of a non-function, non-array type T can be
   //   converted to a prvalue.
-  if (!E->isGLValue()) return Owned(E);
+  if (!E->isGLValue()) return E;
 
   QualType T = E->getType();
   assert(!T.isNull() && "r-value conversion on typeless expression?");
@@ -557,7 +566,7 @@
       (E->getType() == Context.OverloadTy ||
        T->isDependentType() ||
        T->isRecordType()))
-    return Owned(E);
+    return E;
 
   // The C standard is actually really unclear on this point, and
   // DR106 tells us what the result should be but not why.  It's
@@ -565,7 +574,7 @@
   // lvalue-to-rvalue at all.  Note that expressions of unqualified
   // 'void' type are never l-values, but qualified void can be.
   if (T->isVoidType())
-    return Owned(E);
+    return E;
 
   // OpenCL usually rejects direct accesses to values of 'half' type.
   if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16 &&
@@ -612,16 +621,16 @@
       E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
     ExprNeedsCleanups = true;
 
-  ExprResult Res = Owned(ImplicitCastExpr::Create(Context, T, CK_LValueToRValue,
-                                                  E, nullptr, VK_RValue));
+  ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
+                                            nullptr, VK_RValue);
 
   // C11 6.3.2.1p2:
   //   ... if the lvalue has atomic type, the value has the non-atomic version 
   //   of the type of the lvalue ...
   if (const AtomicType *Atomic = T->getAs<AtomicType>()) {
     T = Atomic->getValueType().getUnqualifiedType();
-    Res = Owned(ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic,
-                                         Res.get(), nullptr, VK_RValue));
+    Res = ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic, Res.get(),
+                                   nullptr, VK_RValue);
   }
   
   return Res;
@@ -631,7 +640,7 @@
   ExprResult Res = DefaultFunctionArrayConversion(E);
   if (Res.isInvalid())
     return ExprError();
-  Res = DefaultLvalueConversion(Res.take());
+  Res = DefaultLvalueConversion(Res.get());
   if (Res.isInvalid())
     return ExprError();
   return Res;
@@ -646,14 +655,14 @@
   // to function type.
   if (Ty->isFunctionType()) {
     Res = ImpCastExprToType(E, Context.getPointerType(Ty),
-                            CK_FunctionToPointerDecay).take();
+                            CK_FunctionToPointerDecay).get();
     if (Res.isInvalid())
       return ExprError();
   }
-  Res = DefaultLvalueConversion(Res.take());
+  Res = DefaultLvalueConversion(Res.get());
   if (Res.isInvalid())
     return ExprError();
-  return Owned(Res.take());
+  return Res.get();
 }
 
 /// UsualUnaryConversions - Performs various conversions that are common to most
@@ -666,14 +675,14 @@
   ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
   if (Res.isInvalid())
     return ExprError();
-  E = Res.take();
+  E = Res.get();
 
   QualType Ty = E->getType();
   assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
 
   // Half FP have to be promoted to float unless it is natively supported
   if (Ty->isHalfType() && !getLangOpts().NativeHalfType)
-    return ImpCastExprToType(Res.take(), Context.FloatTy, CK_FloatingCast);
+    return ImpCastExprToType(Res.get(), Context.FloatTy, CK_FloatingCast);
 
   // Try to perform integral promotions if the object has a theoretically
   // promotable type.
@@ -694,16 +703,16 @@
 
     QualType PTy = Context.isPromotableBitField(E);
     if (!PTy.isNull()) {
-      E = ImpCastExprToType(E, PTy, CK_IntegralCast).take();
-      return Owned(E);
+      E = ImpCastExprToType(E, PTy, CK_IntegralCast).get();
+      return E;
     }
     if (Ty->isPromotableIntegerType()) {
       QualType PT = Context.getPromotedIntegerType(Ty);
-      E = ImpCastExprToType(E, PT, CK_IntegralCast).take();
-      return Owned(E);
+      E = ImpCastExprToType(E, PT, CK_IntegralCast).get();
+      return E;
     }
   }
-  return Owned(E);
+  return E;
 }
 
 /// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
@@ -717,14 +726,14 @@
   ExprResult Res = UsualUnaryConversions(E);
   if (Res.isInvalid())
     return ExprError();
-  E = Res.take();
+  E = Res.get();
 
   // If this is a 'float' or '__fp16' (CVR qualified or typedef) promote to
   // double.
   const BuiltinType *BTy = Ty->getAs<BuiltinType>();
   if (BTy && (BTy->getKind() == BuiltinType::Half ||
               BTy->getKind() == BuiltinType::Float))
-    E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).take();
+    E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
 
   // C++ performs lvalue-to-rvalue conversion as a default argument
   // promotion, even on class types, but note:
@@ -740,14 +749,13 @@
   if (getLangOpts().CPlusPlus && E->isGLValue() && !isUnevaluatedContext()) {
     ExprResult Temp = PerformCopyInitialization(
                        InitializedEntity::InitializeTemporary(E->getType()),
-                                                E->getExprLoc(),
-                                                Owned(E));
+                                                E->getExprLoc(), E);
     if (Temp.isInvalid())
       return ExprError();
     E = Temp.get();
   }
 
-  return Owned(E);
+  return E;
 }
 
 /// Determine the degree of POD-ness for an expression.
@@ -856,14 +864,14 @@
       ExprResult ExprRes = CheckPlaceholderExpr(E);
       if (ExprRes.isInvalid())
         return ExprError();
-      E = ExprRes.take();
+      E = ExprRes.get();
     }
   }
   
   ExprResult ExprRes = DefaultArgumentPromotion(E);
   if (ExprRes.isInvalid())
     return ExprError();
-  E = ExprRes.take();
+  E = ExprRes.get();
 
   // Diagnostics regarding non-POD argument types are
   // emitted along with format string checking in Sema::CheckFunctionCall().
@@ -897,7 +905,7 @@
                           diag::err_call_incomplete_argument))
     return ExprError();
 
-  return Owned(E);
+  return E;
 }
 
 /// \brief Converts an integer to complex float type.  Helper function of
@@ -914,12 +922,12 @@
   if (SkipCast) return false;
   if (IntTy->isIntegerType()) {
     QualType fpTy = cast<ComplexType>(ComplexTy)->getElementType();
-    IntExpr = S.ImpCastExprToType(IntExpr.take(), fpTy, CK_IntegralToFloating);
-    IntExpr = S.ImpCastExprToType(IntExpr.take(), ComplexTy,
+    IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating);
+    IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy,
                                   CK_FloatingRealToComplex);
   } else {
     assert(IntTy->isComplexIntegerType());
-    IntExpr = S.ImpCastExprToType(IntExpr.take(), ComplexTy,
+    IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy,
                                   CK_IntegralComplexToFloatingComplex);
   }
   return false;
@@ -937,12 +945,12 @@
   if (order < 0) {
     // _Complex float -> _Complex double
     if (!IsCompAssign)
-      LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_FloatingComplexCast);
+      LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingComplexCast);
     return RHSType;
   }
   if (order > 0)
     // _Complex float -> _Complex double
-    RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_FloatingComplexCast);
+    RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingComplexCast);
   return LHSType;
 }
 
@@ -963,8 +971,8 @@
     // float -> _Complex double
     if (ConvertOtherExpr) {
       QualType fp = cast<ComplexType>(ComplexTy)->getElementType();
-      OtherExpr = S.ImpCastExprToType(OtherExpr.take(), fp, CK_FloatingCast);
-      OtherExpr = S.ImpCastExprToType(OtherExpr.take(), ComplexTy,
+      OtherExpr = S.ImpCastExprToType(OtherExpr.get(), fp, CK_FloatingCast);
+      OtherExpr = S.ImpCastExprToType(OtherExpr.get(), ComplexTy,
                                       CK_FloatingRealToComplex);
     }
     return ComplexTy;
@@ -976,12 +984,12 @@
 
   // double -> _Complex double
   if (ConvertOtherExpr)
-    OtherExpr = S.ImpCastExprToType(OtherExpr.take(), result,
+    OtherExpr = S.ImpCastExprToType(OtherExpr.get(), result,
                                     CK_FloatingRealToComplex);
 
   // _Complex float -> _Complex double
   if (ConvertComplexExpr && order < 0)
-    ComplexExpr = S.ImpCastExprToType(ComplexExpr.take(), result,
+    ComplexExpr = S.ImpCastExprToType(ComplexExpr.get(), result,
                                       CK_FloatingComplexCast);
 
   return result;
@@ -1043,7 +1051,7 @@
   if (IntTy->isIntegerType()) {
     if (ConvertInt)
       // Convert intExpr to the lhs floating point type.
-      IntExpr = S.ImpCastExprToType(IntExpr.take(), FloatTy,
+      IntExpr = S.ImpCastExprToType(IntExpr.get(), FloatTy,
                                     CK_IntegralToFloating);
     return FloatTy;
   }
@@ -1054,12 +1062,12 @@
 
   // _Complex int -> _Complex float
   if (ConvertInt)
-    IntExpr = S.ImpCastExprToType(IntExpr.take(), result,
+    IntExpr = S.ImpCastExprToType(IntExpr.get(), result,
                                   CK_IntegralComplexToFloatingComplex);
 
   // float -> _Complex float
   if (ConvertFloat)
-    FloatExpr = S.ImpCastExprToType(FloatExpr.take(), result,
+    FloatExpr = S.ImpCastExprToType(FloatExpr.get(), result,
                                     CK_FloatingRealToComplex);
 
   return result;
@@ -1078,13 +1086,13 @@
   if (LHSFloat && RHSFloat) {
     int order = S.Context.getFloatingTypeOrder(LHSType, RHSType);
     if (order > 0) {
-      RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_FloatingCast);
+      RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingCast);
       return LHSType;
     }
 
     assert(order < 0 && "illegal float comparison");
     if (!IsCompAssign)
-      LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_FloatingCast);
+      LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingCast);
     return RHSType;
   }
 
@@ -1126,29 +1134,29 @@
   if (LHSSigned == RHSSigned) {
     // Same signedness; use the higher-ranked type
     if (order >= 0) {
-      RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+      RHS = (*doRHSCast)(S, RHS.get(), LHSType);
       return LHSType;
     } else if (!IsCompAssign)
-      LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+      LHS = (*doLHSCast)(S, LHS.get(), RHSType);
     return RHSType;
   } else if (order != (LHSSigned ? 1 : -1)) {
     // The unsigned type has greater than or equal rank to the
     // signed type, so use the unsigned type
     if (RHSSigned) {
-      RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+      RHS = (*doRHSCast)(S, RHS.get(), LHSType);
       return LHSType;
     } else if (!IsCompAssign)
-      LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+      LHS = (*doLHSCast)(S, LHS.get(), RHSType);
     return RHSType;
   } else if (S.Context.getIntWidth(LHSType) != S.Context.getIntWidth(RHSType)) {
     // The two types are different widths; if we are here, that
     // means the signed type is larger than the unsigned type, so
     // use the signed type.
     if (LHSSigned) {
-      RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+      RHS = (*doRHSCast)(S, RHS.get(), LHSType);
       return LHSType;
     } else if (!IsCompAssign)
-      LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+      LHS = (*doLHSCast)(S, LHS.get(), RHSType);
     return RHSType;
   } else {
     // The signed type is higher-ranked than the unsigned type,
@@ -1157,9 +1165,9 @@
     // to the signed type.
     QualType result =
       S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType);
-    RHS = (*doRHSCast)(S, RHS.take(), result);
+    RHS = (*doRHSCast)(S, RHS.get(), result);
     if (!IsCompAssign)
-      LHS = (*doLHSCast)(S, LHS.take(), result);
+      LHS = (*doLHSCast)(S, LHS.get(), result);
     return result;
   }
 }
@@ -1189,7 +1197,7 @@
       handleIntegerConversion<doComplexIntegralCast, doIntegralCast>
         (S, LHS, RHS, LHSEltType, RHSType, IsCompAssign);
     QualType ComplexType = S.Context.getComplexType(ScalarType);
-    RHS = S.ImpCastExprToType(RHS.take(), ComplexType,
+    RHS = S.ImpCastExprToType(RHS.get(), ComplexType,
                               CK_IntegralRealToComplex);
  
     return ComplexType;
@@ -1204,7 +1212,7 @@
   QualType ComplexType = S.Context.getComplexType(ScalarType);
   
   if (!IsCompAssign)
-    LHS = S.ImpCastExprToType(LHS.take(), ComplexType,
+    LHS = S.ImpCastExprToType(LHS.get(), ComplexType,
                               CK_IntegralRealToComplex);
   return ComplexType;
 }
@@ -1216,12 +1224,12 @@
 QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
                                           bool IsCompAssign) {
   if (!IsCompAssign) {
-    LHS = UsualUnaryConversions(LHS.take());
+    LHS = UsualUnaryConversions(LHS.get());
     if (LHS.isInvalid())
       return QualType();
   }
 
-  RHS = UsualUnaryConversions(RHS.take());
+  RHS = UsualUnaryConversions(RHS.get());
   if (RHS.isInvalid())
     return QualType();
 
@@ -1253,7 +1261,7 @@
   if (!LHSBitfieldPromoteTy.isNull())
     LHSType = LHSBitfieldPromoteTy;
   if (LHSType != LHSUnpromotedType && !IsCompAssign)
-    LHS = ImpCastExprToType(LHS.take(), LHSType, CK_IntegralCast);
+    LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast);
 
   // If both types are identical, no conversion is needed.
   if (LHSType == RHSType)
@@ -1325,7 +1333,7 @@
   if (ControllingExpr->getType()->isPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(ControllingExpr);
     if (result.isInvalid()) return ExprError();
-    ControllingExpr = result.take();
+    ControllingExpr = result.get();
   }
 
   bool TypeErrorFound = false,
@@ -1387,10 +1395,9 @@
   // If we determined that the generic selection is result-dependent, don't
   // try to compute the result expression.
   if (IsResultDependent)
-    return Owned(new (Context) GenericSelectionExpr(
-                   Context, KeyLoc, ControllingExpr,
-                   Types, Exprs,
-                   DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack));
+    return new (Context) GenericSelectionExpr(
+        Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc,
+        ContainsUnexpandedParameterPack);
 
   SmallVector<unsigned, 1> CompatIndices;
   unsigned DefaultIndex = -1U;
@@ -1442,11 +1449,9 @@
   unsigned ResultIndex =
     CompatIndices.size() ? CompatIndices[0] : DefaultIndex;
 
-  return Owned(new (Context) GenericSelectionExpr(
-                 Context, KeyLoc, ControllingExpr,
-                 Types, Exprs,
-                 DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack,
-                 ResultIndex));
+  return new (Context) GenericSelectionExpr(
+      Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc,
+      ContainsUnexpandedParameterPack, ResultIndex);
 }
 
 /// getUDSuffixLoc - Create a SourceLocation for a ud-suffix, given the
@@ -1494,16 +1499,15 @@
 /// string.
 ///
 ExprResult
-Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks,
-                         Scope *UDLScope) {
-  assert(NumStringToks && "Must have at least one string!");
+Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
+  assert(!StringToks.empty() && "Must have at least one string!");
 
-  StringLiteralParser Literal(StringToks, NumStringToks, PP);
+  StringLiteralParser Literal(StringToks, PP);
   if (Literal.hadError)
     return ExprError();
 
   SmallVector<SourceLocation, 4> StringTokLocs;
-  for (unsigned i = 0; i != NumStringToks; ++i)
+  for (unsigned i = 0; i != StringToks.size(); ++i)
     StringTokLocs.push_back(StringToks[i].getLocation());
 
   QualType CharTy = Context.CharTy;
@@ -1546,7 +1550,7 @@
                                              &StringTokLocs[0],
                                              StringTokLocs.size());
   if (Literal.getUDSuffix().empty())
-    return Owned(Lit);
+    return Lit;
 
   // We're building a user-defined literal.
   IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
@@ -1671,20 +1675,16 @@
   MarkDeclRefReferenced(E);
 
   if (getLangOpts().ObjCARCWeak && isa<VarDecl>(D) &&
-      Ty.getObjCLifetime() == Qualifiers::OCL_Weak) {
-    DiagnosticsEngine::Level Level =
-      Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                               E->getLocStart());
-    if (Level != DiagnosticsEngine::Ignored)
+      Ty.getObjCLifetime() == Qualifiers::OCL_Weak &&
+      !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart()))
       recordUseOfEvaluatedWeak(E);
-  }
 
   // Just in case we're building an illegal pointer-to-member.
   FieldDecl *FD = dyn_cast<FieldDecl>(D);
   if (FD && FD->isBitField())
     E->setObjectKind(OK_BitField);
 
-  return Owned(E);
+  return E;
 }
 
 /// Decomposes the given name into a DeclarationNameInfo, its location, and
@@ -1767,7 +1767,7 @@
         // TODO: fixit for inserting 'Base<T>::' in the other cases.
         // Actually quite difficult!
         if (getLangOpts().MSVCCompat)
-          diagnostic = diag::warn_found_via_dependent_bases_lookup;
+          diagnostic = diag::ext_found_via_dependent_bases_lookup;
         if (isInstance) {
           Diag(R.getNameLoc(), diagnostic) << Name
             << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
@@ -1882,6 +1882,17 @@
         }
       }
       R.addDecl(ND);
+      if (getLangOpts().CPlusPlus && ND->isCXXClassMember()) {
+        CXXRecordDecl *Record = nullptr;
+        if (Corrected.getCorrectionSpecifier()) {
+          const Type *Ty = Corrected.getCorrectionSpecifier()->getAsType();
+          Record = Ty->getAsCXXRecordDecl();
+        }
+        if (!Record)
+          Record = cast<CXXRecordDecl>(
+              ND->getDeclContext()->getRedeclContext());
+        R.setNamingClass(Record);
+      }
 
       AcceptableWithRecovery =
           isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND);
@@ -1932,6 +1943,53 @@
   return true;
 }
 
+/// In Microsoft mode, if we are inside a template class whose parent class has
+/// dependent base classes, and we can't resolve an unqualified identifier, then
+/// assume the identifier is a member of a dependent base class.  We can only
+/// recover successfully in static methods, instance methods, and other contexts
+/// where 'this' is available.  This doesn't precisely match MSVC's
+/// instantiation model, but it's close enough.
+static Expr *
+recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context,
+                               DeclarationNameInfo &NameInfo,
+                               SourceLocation TemplateKWLoc,
+                               const TemplateArgumentListInfo *TemplateArgs) {
+  // Only try to recover from lookup into dependent bases in static methods or
+  // contexts where 'this' is available.
+  QualType ThisType = S.getCurrentThisType();
+  const CXXRecordDecl *RD = nullptr;
+  if (!ThisType.isNull())
+    RD = ThisType->getPointeeType()->getAsCXXRecordDecl();
+  else if (auto *MD = dyn_cast<CXXMethodDecl>(S.CurContext))
+    RD = MD->getParent();
+  if (!RD || !RD->hasAnyDependentBases())
+    return nullptr;
+
+  // Diagnose this as unqualified lookup into a dependent base class.  If 'this'
+  // is available, suggest inserting 'this->' as a fixit.
+  SourceLocation Loc = NameInfo.getLoc();
+  auto DB = S.Diag(Loc, diag::ext_undeclared_unqual_id_with_dependent_base);
+  DB << NameInfo.getName() << RD;
+
+  if (!ThisType.isNull()) {
+    DB << FixItHint::CreateInsertion(Loc, "this->");
+    return CXXDependentScopeMemberExpr::Create(
+        Context, /*This=*/nullptr, ThisType, /*IsArrow=*/true,
+        /*Op=*/SourceLocation(), NestedNameSpecifierLoc(), TemplateKWLoc,
+        /*FirstQualifierInScope=*/nullptr, NameInfo, TemplateArgs);
+  }
+
+  // Synthesize a fake NNS that points to the derived class.  This will
+  // perform name lookup during template instantiation.
+  CXXScopeSpec SS;
+  auto *NNS =
+      NestedNameSpecifier::Create(Context, nullptr, true, RD->getTypeForDecl());
+  SS.MakeTrivial(Context, NNS, SourceRange(Loc, Loc));
+  return DependentScopeDeclRefExpr::Create(
+      Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+      TemplateArgs);
+}
+
 ExprResult Sema::ActOnIdExpression(Scope *S,
                                    CXXScopeSpec &SS,
                                    SourceLocation TemplateKWLoc,
@@ -2019,77 +2077,59 @@
       if (E.isInvalid())
         return ExprError();
 
-      if (Expr *Ex = E.takeAs<Expr>())
-        return Owned(Ex);
+      if (Expr *Ex = E.getAs<Expr>())
+        return Ex;
     }
   }
 
   if (R.isAmbiguous())
     return ExprError();
 
+  // This could be an implicitly declared function reference (legal in C90,
+  // extension in C99, forbidden in C++).
+  if (R.empty() && HasTrailingLParen && II && !getLangOpts().CPlusPlus) {
+    NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
+    if (D) R.addDecl(D);
+  }
+
   // Determine whether this name might be a candidate for
   // argument-dependent lookup.
   bool ADL = UseArgumentDependentLookup(SS, R, HasTrailingLParen);
 
   if (R.empty() && !ADL) {
-
-    // Otherwise, this could be an implicitly declared function reference (legal
-    // in C90, extension in C99, forbidden in C++).
-    if (HasTrailingLParen && II && !getLangOpts().CPlusPlus) {
-      NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
-      if (D) R.addDecl(D);
+    if (SS.isEmpty() && getLangOpts().MSVCCompat) {
+      if (Expr *E = recoverFromMSUnqualifiedLookup(*this, Context, NameInfo,
+                                                   TemplateKWLoc, TemplateArgs))
+        return E;
     }
 
+    // Don't diagnose an empty lookup for inline assembly.
+    if (IsInlineAsmIdentifier)
+      return ExprError();
+
     // If this name wasn't predeclared and if this is not a function
     // call, diagnose the problem.
-    if (R.empty()) {
-      // In Microsoft mode, if we are inside a template class member function
-      // whose parent class has dependent base classes, and we can't resolve
-      // an unqualified identifier, then assume the identifier is a member of a
-      // dependent base class.  The goal is to postpone name lookup to
-      // instantiation time to be able to search into the type dependent base
-      // classes.
-      // FIXME: If we want 100% compatibility with MSVC, we will have delay all
-      // unqualified name lookup.  Any name lookup during template parsing means
-      // clang might find something that MSVC doesn't.  For now, we only handle
-      // the common case of members of a dependent base class.
-      if (SS.isEmpty() && getLangOpts().MSVCCompat) {
-        CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext);
-        if (MD && MD->isInstance() && MD->getParent()->hasAnyDependentBases()) {
-          QualType ThisType = MD->getThisType(Context);
-          // Since the 'this' expression is synthesized, we don't need to
-          // perform the double-lookup check.
-          NamedDecl *FirstQualifierInScope = nullptr;
-          return Owned(CXXDependentScopeMemberExpr::Create(
-              Context, /*This=*/nullptr, ThisType, /*IsArrow=*/true,
-              /*Op=*/SourceLocation(), SS.getWithLocInContext(Context),
-              TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs));
-        }
-      }
+    CorrectionCandidateCallback DefaultValidator;
+    DefaultValidator.IsAddressOfOperand = IsAddressOfOperand;
+    assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) &&
+           "Typo correction callback misconfigured");
+    if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator))
+      return ExprError();
 
-      // Don't diagnose an empty lookup for inline assmebly.
-      if (IsInlineAsmIdentifier)
+    assert(!R.empty() &&
+           "DiagnoseEmptyLookup returned false but added no results");
+
+    // If we found an Objective-C instance variable, let
+    // LookupInObjCMethod build the appropriate expression to
+    // reference the ivar.
+    if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
+      R.clear();
+      ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+      // In a hopelessly buggy code, Objective-C instance variable
+      // lookup fails and no expression will be built to reference it.
+      if (!E.isInvalid() && !E.get())
         return ExprError();
-
-      CorrectionCandidateCallback DefaultValidator;
-      if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator))
-        return ExprError();
-
-      assert(!R.empty() &&
-             "DiagnoseEmptyLookup returned false but added no results");
-
-      // If we found an Objective-C instance variable, let
-      // LookupInObjCMethod build the appropriate expression to
-      // reference the ivar.
-      if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
-        R.clear();
-        ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
-        // In a hopelessly buggy code, Objective-C instance variable
-        // lookup fails and no expression will be built to reference it.
-        if (!E.isInvalid() && !E.get())
-          return ExprError();
-        return E;
-      }
+      return E;
     }
   }
 
@@ -2164,7 +2204,8 @@
 ExprResult
 Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
                                         const DeclarationNameInfo &NameInfo,
-                                        bool IsAddressOfOperand) {
+                                        bool IsAddressOfOperand,
+                                        TypeSourceInfo **RecoveryTSI) {
   DeclContext *DC = computeDeclContext(SS, false);
   if (!DC)
     return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
@@ -2189,6 +2230,41 @@
     return ExprError();
   }
 
+  if (const TypeDecl *TD = R.getAsSingle<TypeDecl>()) {
+    // Diagnose a missing typename if this resolved unambiguously to a type in
+    // a dependent context.  If we can recover with a type, downgrade this to
+    // a warning in Microsoft compatibility mode.
+    unsigned DiagID = diag::err_typename_missing;
+    if (RecoveryTSI && getLangOpts().MSVCCompat)
+      DiagID = diag::ext_typename_missing;
+    SourceLocation Loc = SS.getBeginLoc();
+    auto D = Diag(Loc, DiagID);
+    D << SS.getScopeRep() << NameInfo.getName().getAsString()
+      << SourceRange(Loc, NameInfo.getEndLoc());
+
+    // Don't recover if the caller isn't expecting us to or if we're in a SFINAE
+    // context.
+    if (!RecoveryTSI)
+      return ExprError();
+
+    // Only issue the fixit if we're prepared to recover.
+    D << FixItHint::CreateInsertion(Loc, "typename ");
+
+    // Recover by pretending this was an elaborated type.
+    QualType Ty = Context.getTypeDeclType(TD);
+    TypeLocBuilder TLB;
+    TLB.pushTypeSpec(Ty).setNameLoc(NameInfo.getLoc());
+
+    QualType ET = getElaboratedType(ETK_None, SS, Ty);
+    ElaboratedTypeLoc QTL = TLB.push<ElaboratedTypeLoc>(ET);
+    QTL.setElaboratedKeywordLoc(SourceLocation());
+    QTL.setQualifierLoc(SS.getWithLocInContext(Context));
+
+    *RecoveryTSI = TLB.getTypeSourceInfo(Context, ET);
+
+    return ExprEmpty();
+  }
+
   // Defend against this resolving to an implicit member access. We usually
   // won't get here if this might be a legitimate a class member (we end up in
   // BuildMemberReferenceExpr instead), but this can be valid if we're forming
@@ -2277,7 +2353,7 @@
       if (SelfExpr.isInvalid())
         return ExprError();
 
-      SelfExpr = DefaultLvalueConversion(SelfExpr.take());
+      SelfExpr = DefaultLvalueConversion(SelfExpr.get());
       if (SelfExpr.isInvalid())
         return ExprError();
 
@@ -2290,14 +2366,12 @@
 
       ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
                                                               Loc, IV->getLocation(),
-                                                              SelfExpr.take(),
+                                                              SelfExpr.get(),
                                                               true, true);
 
       if (getLangOpts().ObjCAutoRefCount) {
         if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
-          DiagnosticsEngine::Level Level =
-            Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, Loc);
-          if (Level != DiagnosticsEngine::Ignored)
+          if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
             recordUseOfEvaluatedWeak(Result);
         }
         if (CurContext->isClosure())
@@ -2305,7 +2379,7 @@
             << FixItHint::CreateInsertion(Loc, "self->");
       }
       
-      return Owned(Result);
+      return Result;
     }
   } else if (CurMethod->isInstanceMethod()) {
     // We should warn if a local variable hides an ivar.
@@ -2338,7 +2412,7 @@
     }
   }
   // Sentinel value saying that we didn't do anything special.
-  return Owned((Expr*) nullptr);
+  return ExprResult((Expr *)nullptr);
 }
 
 /// \brief Cast a base object to a member's actual type.
@@ -2365,7 +2439,7 @@
                                     NamedDecl *Member) {
   CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext());
   if (!RD)
-    return Owned(From);
+    return From;
 
   QualType DestRecordType;
   QualType DestType;
@@ -2385,7 +2459,7 @@
     }
   } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) {
     if (Method->isStatic())
-      return Owned(From);
+      return From;
 
     DestType = Method->getThisType(Context);
     DestRecordType = DestType->getPointeeType();
@@ -2399,15 +2473,15 @@
     }
   } else {
     // No conversion necessary.
-    return Owned(From);
+    return From;
   }
 
   if (DestType->isDependentType() || FromType->isDependentType())
-    return Owned(From);
+    return From;
 
   // If the unqualified types are the same, no conversion is necessary.
   if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
-    return Owned(From);
+    return From;
 
   SourceRange FromRange = From->getSourceRange();
   SourceLocation FromLoc = FromRange.getBegin();
@@ -2450,7 +2524,7 @@
       if (PointerConversions)
         QType = Context.getPointerType(QType);
       From = ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase,
-                               VK, &BasePath).take();
+                               VK, &BasePath).get();
 
       FromType = QType;
       FromRecordType = QRecordType;
@@ -2458,7 +2532,7 @@
       // If the qualifier type was the same as the destination type,
       // we're done.
       if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
-        return Owned(From);
+        return From;
     }
   }
 
@@ -2487,7 +2561,7 @@
       if (PointerConversions)
         UType = Context.getPointerType(UType);
       From = ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase,
-                               VK, &BasePath).take();
+                               VK, &BasePath).get();
       FromType = UType;
       FromRecordType = URecordType;
     }
@@ -2615,7 +2689,7 @@
                                    NeedsADL, R.isOverloadedResult(),
                                    R.begin(), R.end());
 
-  return Owned(ULE);
+  return ULE;
 }
 
 /// \brief Complete semantic analysis for a reference to the given declaration.
@@ -2862,7 +2936,7 @@
     ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
   }
 
-  return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
+  return new (Context) PredefinedExpr(Loc, ResTy, IT);
 }
 
 ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
@@ -2917,7 +2991,7 @@
                                              Tok.getLocation());
 
   if (Literal.getUDSuffix().empty())
-    return Owned(Lit);
+    return Lit;
 
   // We're building a user-defined literal.
   IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
@@ -2936,8 +3010,8 @@
 
 ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
   unsigned IntSize = Context.getTargetInfo().getIntWidth();
-  return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
-                                      Context.IntTy, Loc));
+  return IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
+                                Context.IntTy, Loc);
 }
 
 static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,
@@ -3102,10 +3176,10 @@
 
     if (Ty == Context.DoubleTy) {
       if (getLangOpts().SinglePrecisionConstants) {
-        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take();
+        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
       } else if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp64) {
         Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64);
-        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take();
+        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
       }
     }
   } else if (!Literal.isIntegerLiteral()) {
@@ -3129,7 +3203,7 @@
     // may be wider than [u]intmax_t.
     // FIXME: Actually, they don't. We seem to have accidentally invented the
     //        i128 suffix.
-    if (Literal.isMicrosoftInteger && MaxWidth < 128 &&
+    if (Literal.MicrosoftInteger == 128 && MaxWidth < 128 &&
         Context.getTargetInfo().hasInt128Type())
       MaxWidth = 128;
     llvm::APInt ResultVal(MaxWidth, 0);
@@ -3150,7 +3224,22 @@
 
       // Check from smallest to largest, picking the smallest type we can.
       unsigned Width = 0;
-      if (!Literal.isLong && !Literal.isLongLong) {
+
+      // Microsoft specific integer suffixes are explicitly sized.
+      if (Literal.MicrosoftInteger) {
+        if (Literal.MicrosoftInteger > MaxWidth) {
+          // If this target doesn't support __int128, error and force to ull.
+          Diag(Tok.getLocation(), diag::err_int128_unsupported);
+          Width = MaxWidth;
+          Ty = Context.getIntMaxType();
+        } else {
+          Width = Literal.MicrosoftInteger;
+          Ty = Context.getIntTypeForBitwidth(Width,
+                                             /*Signed=*/!Literal.isUnsigned);
+        }
+      }
+
+      if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong) {
         // Are int/unsigned possibilities?
         unsigned IntSize = Context.getTargetInfo().getIntWidth();
 
@@ -3197,17 +3286,6 @@
           Width = LongLongSize;
         }
       }
-        
-      // If it doesn't fit in unsigned long long, and we're using Microsoft
-      // extensions, then its a 128-bit integer literal.
-      if (Ty.isNull() && Literal.isMicrosoftInteger &&
-          Context.getTargetInfo().hasInt128Type()) {
-        if (Literal.isUnsigned)
-          Ty = Context.UnsignedInt128Ty;
-        else
-          Ty = Context.Int128Ty;
-        Width = 128;
-      }
 
       // If we still couldn't decide a type, we probably have something that
       // does not fit in a signed long long, but has no U suffix.
@@ -3228,12 +3306,12 @@
     Res = new (Context) ImaginaryLiteral(Res,
                                         Context.getComplexType(Res->getType()));
 
-  return Owned(Res);
+  return Res;
 }
 
 ExprResult Sema::ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E) {
   assert(E && "ActOnParenExpr() missing expr");
-  return Owned(new (Context) ParenExpr(L, R, E));
+  return new (Context) ParenExpr(L, R, E);
 }
 
 static bool CheckVecStepTraitOperandType(Sema &S, QualType T,
@@ -3338,10 +3416,21 @@
                                       E->getSourceRange(), ExprKind))
     return false;
 
-  if (RequireCompleteExprType(E,
-                              diag::err_sizeof_alignof_incomplete_type,
-                              ExprKind, E->getSourceRange()))
-    return true;
+  // 'alignof' applied to an expression only requires the base element type of
+  // the expression to be complete. 'sizeof' requires the expression's type to
+  // be complete (and will attempt to complete it if it's an array of unknown
+  // bound).
+  if (ExprKind == UETT_AlignOf) {
+    if (RequireCompleteType(E->getExprLoc(),
+                            Context.getBaseElementType(E->getType()),
+                            diag::err_sizeof_alignof_incomplete_type, ExprKind,
+                            E->getSourceRange()))
+      return true;
+  } else {
+    if (RequireCompleteExprType(E, diag::err_sizeof_alignof_incomplete_type,
+                                ExprKind, E->getSourceRange()))
+      return true;
+  }
 
   // Completing the expression's type may have changed it.
   ExprTy = E->getType();
@@ -3406,13 +3495,21 @@
   if (ExprType->isDependentType())
     return false;
 
-  // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
-  //   the result is the size of the referenced type."
-  // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
-  //   result shall be the alignment of the referenced type."
+  // C++ [expr.sizeof]p2:
+  //     When applied to a reference or a reference type, the result
+  //     is the size of the referenced type.
+  // C++11 [expr.alignof]p3:
+  //     When alignof is applied to a reference type, the result
+  //     shall be the alignment of the referenced type.
   if (const ReferenceType *Ref = ExprType->getAs<ReferenceType>())
     ExprType = Ref->getPointeeType();
 
+  // C11 6.5.3.4/3, C++11 [expr.alignof]p3:
+  //   When alignof or _Alignof is applied to an array type, the result
+  //   is the alignment of the element type.
+  if (ExprKind == UETT_AlignOf)
+    ExprType = Context.getBaseElementType(ExprType);
+
   if (ExprKind == UETT_VecStep)
     return CheckVecStepTraitOperandType(*this, ExprType, OpLoc, ExprRange);
 
@@ -3462,21 +3559,10 @@
   // If it's a field, require the containing struct to have a
   // complete definition so that we can compute the layout.
   //
-  // This requires a very particular set of circumstances.  For a
-  // field to be contained within an incomplete type, we must in the
-  // process of parsing that type.  To have an expression refer to a
-  // field, it must be an id-expression or a member-expression, but
-  // the latter are always ill-formed when the base type is
-  // incomplete, including only being partially complete.  An
-  // id-expression can never refer to a field in C because fields
-  // are not in the ordinary namespace.  In C++, an id-expression
-  // can implicitly be a member access, but only if there's an
-  // implicit 'this' value, and all such contexts are subject to
-  // delayed parsing --- except for trailing return types in C++11.
-  // And if an id-expression referring to a field occurs in a
-  // context that lacks a 'this' value, it's ill-formed --- except,
-  // again, in C++11, where such references are allowed in an
-  // unevaluated context.  So C++11 introduces some new complexity.
+  // This can happen in C++11 onwards, either by naming the member
+  // in a way that is not transformed into a member access expression
+  // (in an unevaluated operand, for instance), or by naming the member
+  // in a trailing-return-type.
   //
   // For the record, since __alignof__ on expressions is a GCC
   // extension, GCC seems to permit this but always gives the
@@ -3533,9 +3619,8 @@
     return ExprError();
 
   // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
-  return Owned(new (Context) UnaryExprOrTypeTraitExpr(ExprKind, TInfo,
-                                                      Context.getSizeType(),
-                                                      OpLoc, R.getEnd()));
+  return new (Context) UnaryExprOrTypeTraitExpr(
+      ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
 }
 
 /// \brief Build a sizeof or alignof expression given an expression
@@ -3570,13 +3655,12 @@
   if (ExprKind == UETT_SizeOf && E->getType()->isVariableArrayType()) {
     PE = TransformToPotentiallyEvaluated(E);
     if (PE.isInvalid()) return ExprError();
-    E = PE.take();
+    E = PE.get();
   }
 
   // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
-  return Owned(new (Context) UnaryExprOrTypeTraitExpr(
-      ExprKind, E, Context.getSizeType(), OpLoc,
-      E->getSourceRange().getEnd()));
+  return new (Context) UnaryExprOrTypeTraitExpr(
+      ExprKind, E, Context.getSizeType(), OpLoc, E->getSourceRange().getEnd());
 }
 
 /// ActOnUnaryExprOrTypeTraitExpr - Handle @c sizeof(type) and @c sizeof @c
@@ -3607,7 +3691,7 @@
 
   // _Real and _Imag are only l-values for normal l-values.
   if (V.get()->getObjectKind() != OK_Ordinary) {
-    V = S.DefaultLvalueConversion(V.take());
+    V = S.DefaultLvalueConversion(V.get());
     if (V.isInvalid())
       return QualType();
   }
@@ -3649,7 +3733,7 @@
   // Since this might is a postfix expression, get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Input);
   if (Result.isInvalid()) return ExprError();
-  Input = Result.take();
+  Input = Result.get();
 
   return BuildUnaryOp(S, OpLoc, Opc, Input);
 }
@@ -3678,7 +3762,7 @@
   if (isa<ParenListExpr>(base)) {
     ExprResult result = MaybeConvertParenListExprToParenExpr(S, base);
     if (result.isInvalid()) return ExprError();
-    base = result.take();
+    base = result.get();
   }
 
   // Handle any non-overload placeholder types in the base and index
@@ -3689,21 +3773,19 @@
   if (base->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(base);
     if (result.isInvalid()) return ExprError();
-    base = result.take();
+    base = result.get();
   }
   if (idx->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(idx);
     if (result.isInvalid()) return ExprError();
-    idx = result.take();
+    idx = result.get();
   }
 
   // Build an unanalyzed expression if either operand is type-dependent.
   if (getLangOpts().CPlusPlus &&
       (base->isTypeDependent() || idx->isTypeDependent())) {
-    return Owned(new (Context) ArraySubscriptExpr(base, idx,
-                                                  Context.DependentTy,
-                                                  VK_LValue, OK_Ordinary,
-                                                  rbLoc));
+    return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy,
+                                            VK_LValue, OK_Ordinary, rbLoc);
   }
 
   // Use C++ overloaded-operator rules if either operand has record
@@ -3735,12 +3817,12 @@
     ExprResult Result = DefaultFunctionArrayLvalueConversion(LHSExp);
     if (Result.isInvalid())
       return ExprError();
-    LHSExp = Result.take();
+    LHSExp = Result.get();
   }
   ExprResult Result = DefaultFunctionArrayLvalueConversion(RHSExp);
   if (Result.isInvalid())
     return ExprError();
-  RHSExp = Result.take();
+  RHSExp = Result.get();
 
   QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType();
   ExprValueKind VK = VK_LValue;
@@ -3806,7 +3888,7 @@
     Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
         LHSExp->getSourceRange();
     LHSExp = ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
-                               CK_ArrayToPointerDecay).take();
+                               CK_ArrayToPointerDecay).get();
     LHSTy = LHSExp->getType();
 
     BaseExpr = LHSExp;
@@ -3817,7 +3899,7 @@
     Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
         RHSExp->getSourceRange();
     RHSExp = ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
-                               CK_ArrayToPointerDecay).take();
+                               CK_ArrayToPointerDecay).get();
     RHSTy = RHSExp->getType();
 
     BaseExpr = RHSExp;
@@ -3863,8 +3945,8 @@
   assert(VK == VK_RValue || LangOpts.CPlusPlus ||
          !ResultType.isCForbiddenLValueType());
 
-  return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
-                                                ResultType, VK, OK, RLoc));
+  return new (Context)
+      ArraySubscriptExpr(LHSExp, RHSExp, ResultType, VK, OK, RLoc);
 }
 
 ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
@@ -3913,17 +3995,17 @@
     InitializationKind Kind
       = InitializationKind::CreateCopy(Param->getLocation(),
              /*FIXME:EqualLoc*/UninstExpr->getLocStart());
-    Expr *ResultE = Result.takeAs<Expr>();
+    Expr *ResultE = Result.getAs<Expr>();
 
     InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
     Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
     if (Result.isInvalid())
       return ExprError();
 
-    Expr *Arg = Result.takeAs<Expr>();
+    Expr *Arg = Result.getAs<Expr>();
     CheckCompletedExpr(Arg, Param->getOuterLocStart());
     // Build the default argument expression.
-    return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg));
+    return CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg);
   }
 
   // If the default expression creates temporaries, we need to
@@ -3950,7 +4032,7 @@
   // as being "referenced".
   MarkDeclarationsReferencedInExpr(Param->getDefaultArg(),
                                    /*SkipLocalVariables=*/true);
-  return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param));
+  return CXXDefaultArgExpr::Create(Context, CallLoc, Param);
 }
 
 
@@ -4202,15 +4284,12 @@
       if (CFAudited)
         Entity.setParameterCFAudited();
 
-      ExprResult ArgE = PerformCopyInitialization(Entity,
-                                                  SourceLocation(),
-                                                  Owned(Arg),
-                                                  IsListInitialization,
-                                                  AllowExplicit);
+      ExprResult ArgE = PerformCopyInitialization(
+          Entity, SourceLocation(), Arg, IsListInitialization, AllowExplicit);
       if (ArgE.isInvalid())
         return true;
 
-      Arg = ArgE.takeAs<Expr>();
+      Arg = ArgE.getAs<Expr>();
     } else {
       assert(Param && "can't use default arguments without a known callee");
 
@@ -4219,7 +4298,7 @@
       if (ArgExpr.isInvalid())
         return true;
 
-      Arg = ArgExpr.takeAs<Expr>();
+      Arg = ArgExpr.getAs<Expr>();
     }
 
     // Check for array bounds violations for each argument to the call. This
@@ -4243,7 +4322,7 @@
         QualType paramType; // ignored
         ExprResult arg = checkUnknownAnyArg(CallLoc, Args[i], paramType);
         Invalid |= arg.isInvalid();
-        AllArgs.push_back(arg.take());
+        AllArgs.push_back(arg.get());
       }
 
     // Otherwise do argument promotion, (C99 6.5.2.2p7).
@@ -4252,7 +4331,7 @@
         ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], CallType,
                                                           FDecl);
         Invalid |= Arg.isInvalid();
-        AllArgs.push_back(Arg.take());
+        AllArgs.push_back(Arg.get());
       }
     }
 
@@ -4374,7 +4453,7 @@
     if (isPlaceholderToRemoveAsArg(args[i]->getType())) {
       ExprResult result = S.CheckPlaceholderExpr(args[i]);
       if (result.isInvalid()) hasInvalid = true;
-      else args[i] = result.take();
+      else args[i] = result.get();
     }
   }
   return hasInvalid;
@@ -4390,7 +4469,7 @@
   // Since this might be a postfix expression, get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Fn);
   if (Result.isInvalid()) return ExprError();
-  Fn = Result.take();
+  Fn = Result.get();
 
   if (checkArgsForPlaceholders(*this, ArgExprs))
     return ExprError();
@@ -4406,14 +4485,13 @@
                                                 ArgExprs.back()->getLocEnd()));
       }
 
-      return Owned(new (Context) CallExpr(Context, Fn, None,
-                                          Context.VoidTy, VK_RValue,
-                                          RParenLoc));
+      return new (Context)
+          CallExpr(Context, Fn, None, Context.VoidTy, VK_RValue, RParenLoc);
     }
     if (Fn->getType() == Context.PseudoObjectTy) {
       ExprResult result = CheckPlaceholderExpr(Fn);
       if (result.isInvalid()) return ExprError();
-      Fn = result.take();
+      Fn = result.get();
     }
 
     // Determine whether this is a dependent call inside a C++ template,
@@ -4428,25 +4506,24 @@
 
     if (Dependent) {
       if (ExecConfig) {
-        return Owned(new (Context) CUDAKernelCallExpr(
+        return new (Context) CUDAKernelCallExpr(
             Context, Fn, cast<CallExpr>(ExecConfig), ArgExprs,
-            Context.DependentTy, VK_RValue, RParenLoc));
+            Context.DependentTy, VK_RValue, RParenLoc);
       } else {
-        return Owned(new (Context) CallExpr(Context, Fn, ArgExprs,
-                                            Context.DependentTy, VK_RValue,
-                                            RParenLoc));
+        return new (Context) CallExpr(
+            Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
       }
     }
 
     // Determine whether this is a call to an object (C++ [over.call.object]).
     if (Fn->getType()->isRecordType())
-      return Owned(BuildCallToObjectOfClassType(S, Fn, LParenLoc,
-                                                ArgExprs, RParenLoc));
+      return BuildCallToObjectOfClassType(S, Fn, LParenLoc, ArgExprs,
+                                          RParenLoc);
 
     if (Fn->getType() == Context.UnknownAnyTy) {
       ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
       if (result.isInvalid()) return ExprError();
-      Fn = result.take();
+      Fn = result.get();
     }
 
     if (Fn->getType() == Context.BoundMemberTy) {
@@ -4476,7 +4553,7 @@
   if (Fn->getType() == Context.UnknownAnyTy) {
     ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
     if (result.isInvalid()) return ExprError();
-    Fn = result.take();
+    Fn = result.get();
   }
 
   Expr *NakedFn = Fn->IgnoreParens();
@@ -4544,8 +4621,7 @@
                      << DstTy
                      << SrcTy
                      << E->getSourceRange());
-  return Owned(new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc,
-               RParenLoc));
+  return new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc, RParenLoc);
 }
 
 /// ActOnConvertVectorExpr - create a new convert-vector expression from the
@@ -4583,13 +4659,13 @@
   if (BuiltinID &&
       Fn->getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn)) {
     Result = ImpCastExprToType(Fn, Context.getPointerType(FDecl->getType()),
-                               CK_BuiltinFnToFnPtr).take();
+                               CK_BuiltinFnToFnPtr).get();
   } else {
     Result = CallExprUnaryConversions(Fn);
   }
   if (Result.isInvalid())
     return ExprError();
-  Fn = Result.take();
+  Fn = Result.get();
 
   // Make the call expr early, before semantic checks.  This guarantees cleanup
   // of arguments and function on error.
@@ -4624,7 +4700,7 @@
     if (Fn->getType() == Context.UnknownAnyTy) {
       ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn);
       if (rewrite.isInvalid()) return ExprError();
-      Fn = rewrite.take();
+      Fn = rewrite.get();
       TheCall->setCallee(Fn);
       goto retry;
     }
@@ -4693,13 +4769,12 @@
       if (Proto && i < Proto->getNumParams()) {
         InitializedEntity Entity = InitializedEntity::InitializeParameter(
             Context, Proto->getParamType(i), Proto->isParamConsumed(i));
-        ExprResult ArgE = PerformCopyInitialization(Entity,
-                                                    SourceLocation(),
-                                                    Owned(Arg));
+        ExprResult ArgE =
+            PerformCopyInitialization(Entity, SourceLocation(), Arg);
         if (ArgE.isInvalid())
           return true;
         
-        Arg = ArgE.takeAs<Expr>();
+        Arg = ArgE.getAs<Expr>();
 
       } else {
         ExprResult ArgE = DefaultArgumentPromotion(Arg);
@@ -4707,7 +4782,7 @@
         if (ArgE.isInvalid())
           return true;
 
-        Arg = ArgE.takeAs<Expr>();
+        Arg = ArgE.getAs<Expr>();
       }
       
       if (RequireCompleteType(Arg->getLocStart(),
@@ -4824,7 +4899,7 @@
       // of one failure would be terrible for indexing/etc.
       if (result.isInvalid()) continue;
 
-      InitArgList[I] = result.take();
+      InitArgList[I] = result.get();
     }
   }
 
@@ -4834,7 +4909,7 @@
   InitListExpr *E = new (Context) InitListExpr(Context, LBraceLoc, InitArgList,
                                                RBraceLoc);
   E->setType(Context.VoidTy); // FIXME: just a place holder for now.
-  return Owned(E);
+  return E;
 }
 
 /// Do an explicit extend of the given block pointer if we're in ARC.
@@ -4931,12 +5006,12 @@
     case Type::STK_Floating:
       return CK_IntegralToFloating;
     case Type::STK_IntegralComplex:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               DestTy->castAs<ComplexType>()->getElementType(),
                               CK_IntegralCast);
       return CK_IntegralRealToComplex;
     case Type::STK_FloatingComplex:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               DestTy->castAs<ComplexType>()->getElementType(),
                               CK_IntegralToFloating);
       return CK_FloatingRealToComplex;
@@ -4954,12 +5029,12 @@
     case Type::STK_Integral:
       return CK_FloatingToIntegral;
     case Type::STK_FloatingComplex:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               DestTy->castAs<ComplexType>()->getElementType(),
                               CK_FloatingCast);
       return CK_FloatingRealToComplex;
     case Type::STK_IntegralComplex:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               DestTy->castAs<ComplexType>()->getElementType(),
                               CK_FloatingToIntegral);
       return CK_IntegralRealToComplex;
@@ -4982,13 +5057,13 @@
       QualType ET = SrcTy->castAs<ComplexType>()->getElementType();
       if (Context.hasSameType(ET, DestTy))
         return CK_FloatingComplexToReal;
-      Src = ImpCastExprToType(Src.take(), ET, CK_FloatingComplexToReal);
+      Src = ImpCastExprToType(Src.get(), ET, CK_FloatingComplexToReal);
       return CK_FloatingCast;
     }
     case Type::STK_Bool:
       return CK_FloatingComplexToBoolean;
     case Type::STK_Integral:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               SrcTy->castAs<ComplexType>()->getElementType(),
                               CK_FloatingComplexToReal);
       return CK_FloatingToIntegral;
@@ -5011,13 +5086,13 @@
       QualType ET = SrcTy->castAs<ComplexType>()->getElementType();
       if (Context.hasSameType(ET, DestTy))
         return CK_IntegralComplexToReal;
-      Src = ImpCastExprToType(Src.take(), ET, CK_IntegralComplexToReal);
+      Src = ImpCastExprToType(Src.get(), ET, CK_IntegralComplexToReal);
       return CK_IntegralCast;
     }
     case Type::STK_Bool:
       return CK_IntegralComplexToBoolean;
     case Type::STK_Floating:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               SrcTy->castAs<ComplexType>()->getElementType(),
                               CK_IntegralComplexToReal);
       return CK_IntegralToFloating;
@@ -5116,7 +5191,7 @@
       return ExprError();
     }
     Kind = CK_BitCast;
-    return Owned(CastExpr);
+    return CastExpr;
   }
 
   // All non-pointer scalars can be cast to ExtVector type.  The appropriate
@@ -5128,14 +5203,14 @@
       << DestTy << SrcTy << R;
 
   QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
-  ExprResult CastExprRes = Owned(CastExpr);
+  ExprResult CastExprRes = CastExpr;
   CastKind CK = PrepareScalarCast(CastExprRes, DestElemTy);
   if (CastExprRes.isInvalid())
     return ExprError();
-  CastExpr = ImpCastExprToType(CastExprRes.take(), DestElemTy, CK).take();
+  CastExpr = ImpCastExprToType(CastExprRes.get(), DestElemTy, CK).get();
 
   Kind = CK_VectorSplat;
-  return Owned(CastExpr);
+  return CastExpr;
 }
 
 ExprResult
@@ -5191,7 +5266,7 @@
   if (isa<ParenListExpr>(CastExpr)) {
     ExprResult Result = MaybeConvertParenListExprToParenExpr(S, CastExpr);
     if (Result.isInvalid()) return ExprError();
-    CastExpr = Result.take();
+    CastExpr = Result.get();
   }
 
   if (getLangOpts().CPlusPlus && !castType->isVoidType() &&
@@ -5199,7 +5274,9 @@
     Diag(LParenLoc, diag::warn_old_style_cast) << CastExpr->getSourceRange();
   
   CheckTollFreeBridgeCast(castType, CastExpr);
-
+  
+  CheckObjCBridgeRelatedCast(castType, CastExpr);
+  
   return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, CastExpr);
 }
 
@@ -5246,9 +5323,9 @@
       ExprResult Literal = DefaultLvalueConversion(exprs[0]);
       if (Literal.isInvalid())
         return ExprError();
-      Literal = ImpCastExprToType(Literal.take(), ElemTy,
+      Literal = ImpCastExprToType(Literal.get(), ElemTy,
                                   PrepareScalarCast(Literal, ElemTy));
-      return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
+      return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
     }
     else if (numExprs < numElems) {
       Diag(E->getExprLoc(),
@@ -5268,9 +5345,9 @@
         ExprResult Literal = DefaultLvalueConversion(exprs[0]);
         if (Literal.isInvalid())
           return ExprError();
-        Literal = ImpCastExprToType(Literal.take(), ElemTy,
+        Literal = ImpCastExprToType(Literal.get(), ElemTy,
                                     PrepareScalarCast(Literal, ElemTy));
-        return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
+        return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
     }
     
     initExprs.append(exprs, exprs + numExprs);
@@ -5289,7 +5366,7 @@
 Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
   ParenListExpr *E = dyn_cast<ParenListExpr>(OrigExpr);
   if (!E)
-    return Owned(OrigExpr);
+    return OrigExpr;
 
   ExprResult Result(E->getExpr(0));
 
@@ -5306,7 +5383,7 @@
                                     SourceLocation R,
                                     MultiExprArg Val) {
   Expr *expr = new (Context) ParenListExpr(Context, L, Val, R);
-  return Owned(expr);
+  return expr;
 }
 
 /// \brief Emit a specialized diagnostic when one expression is a null pointer
@@ -5387,8 +5464,8 @@
   }
 
   // Implicity convert these scalars to the type of the condition.
-  LHS = S.ImpCastExprToType(LHS.take(), CondTy, CK_IntegralCast);
-  RHS = S.ImpCastExprToType(RHS.take(), CondTy, CK_IntegralCast);
+  LHS = S.ImpCastExprToType(LHS.get(), CondTy, CK_IntegralCast);
+  RHS = S.ImpCastExprToType(RHS.get(), CondTy, CK_IntegralCast);
   return false;
 }
 
@@ -5404,8 +5481,8 @@
     if (!RHSExpr->getType()->isVoidType())
       S.Diag(LHSExpr->getLocStart(), diag::ext_typecheck_cond_one_void)
         << LHSExpr->getSourceRange();
-    LHS = S.ImpCastExprToType(LHS.take(), S.Context.VoidTy, CK_ToVoid);
-    RHS = S.ImpCastExprToType(RHS.take(), S.Context.VoidTy, CK_ToVoid);
+    LHS = S.ImpCastExprToType(LHS.get(), S.Context.VoidTy, CK_ToVoid);
+    RHS = S.ImpCastExprToType(RHS.get(), S.Context.VoidTy, CK_ToVoid);
     return S.Context.VoidTy;
 }
 
@@ -5418,7 +5495,7 @@
                                             Expr::NPC_ValueDependentIsNull))
     return true;
 
-  NullExpr = S.ImpCastExprToType(NullExpr.take(), PointerTy, CK_NullToPointer);
+  NullExpr = S.ImpCastExprToType(NullExpr.get(), PointerTy, CK_NullToPointer);
   return false;
 }
 
@@ -5477,8 +5554,8 @@
     // reason, but this is what gcc does, and we do have to pick
     // to get a consistent AST.
     QualType incompatTy = S.Context.getPointerType(S.Context.VoidTy);
-    LHS = S.ImpCastExprToType(LHS.take(), incompatTy, CK_BitCast);
-    RHS = S.ImpCastExprToType(RHS.take(), incompatTy, CK_BitCast);
+    LHS = S.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
+    RHS = S.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
     return incompatTy;
   }
 
@@ -5489,11 +5566,41 @@
   else
     ResultTy = S.Context.getPointerType(ResultTy);
 
-  LHS = S.ImpCastExprToType(LHS.take(), ResultTy, CK_BitCast);
-  RHS = S.ImpCastExprToType(RHS.take(), ResultTy, CK_BitCast);
+  LHS = S.ImpCastExprToType(LHS.get(), ResultTy, CK_BitCast);
+  RHS = S.ImpCastExprToType(RHS.get(), ResultTy, CK_BitCast);
   return ResultTy;
 }
 
+/// \brief Returns true if QT is quelified-id and implements 'NSObject' and/or
+/// 'NSCopying' protocols (and nothing else); or QT is an NSObject and optionally
+/// implements 'NSObject' and/or NSCopying' protocols (and nothing else).
+static bool isObjCPtrBlockCompatible(Sema &S, ASTContext &C, QualType QT) {
+  if (QT->isObjCIdType())
+    return true;
+  
+  const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+  if (!OPT)
+    return false;
+
+  if (ObjCInterfaceDecl *ID = OPT->getInterfaceDecl())
+    if (ID->getIdentifier() != &C.Idents.get("NSObject"))
+      return false;
+  
+  ObjCProtocolDecl* PNSCopying =
+    S.LookupProtocol(&C.Idents.get("NSCopying"), SourceLocation());
+  ObjCProtocolDecl* PNSObject =
+    S.LookupProtocol(&C.Idents.get("NSObject"), SourceLocation());
+
+  for (auto *Proto : OPT->quals()) {
+    if ((PNSCopying && declaresSameEntity(Proto, PNSCopying)) ||
+        (PNSObject && declaresSameEntity(Proto, PNSObject)))
+      ;
+    else
+      return false;
+  }
+  return true;
+}
+
 /// \brief Return the resulting type when the operands are both block pointers.
 static QualType checkConditionalBlockPointerCompatibility(Sema &S,
                                                           ExprResult &LHS,
@@ -5505,8 +5612,8 @@
   if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
     if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
       QualType destType = S.Context.getPointerType(S.Context.VoidTy);
-      LHS = S.ImpCastExprToType(LHS.take(), destType, CK_BitCast);
-      RHS = S.ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+      LHS = S.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
+      RHS = S.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
       return destType;
     }
     S.Diag(Loc, diag::err_typecheck_cond_incompatible_operands)
@@ -5539,9 +5646,9 @@
       = S.Context.getQualifiedType(lhptee, rhptee.getQualifiers());
     QualType destType = S.Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    LHS = S.ImpCastExprToType(LHS.take(), destType, CK_NoOp);
+    LHS = S.ImpCastExprToType(LHS.get(), destType, CK_NoOp);
     // Promote to void*.
-    RHS = S.ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+    RHS = S.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
     return destType;
   }
   if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
@@ -5549,9 +5656,9 @@
       = S.Context.getQualifiedType(rhptee, lhptee.getQualifiers());
     QualType destType = S.Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    RHS = S.ImpCastExprToType(RHS.take(), destType, CK_NoOp);
+    RHS = S.ImpCastExprToType(RHS.get(), destType, CK_NoOp);
     // Promote to void*.
-    LHS = S.ImpCastExprToType(LHS.take(), destType, CK_BitCast);
+    LHS = S.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
     return destType;
   }
 
@@ -5573,7 +5680,7 @@
   S.Diag(Loc, diag::warn_typecheck_cond_pointer_integer_mismatch)
     << Expr1->getType() << Expr2->getType()
     << Expr1->getSourceRange() << Expr2->getSourceRange();
-  Int = S.ImpCastExprToType(Int.take(), PointerExpr->getType(),
+  Int = S.ImpCastExprToType(Int.get(), PointerExpr->getType(),
                             CK_IntegralToPointer);
   return true;
 }
@@ -5602,7 +5709,7 @@
   OK = OK_Ordinary;
 
   // First, check the condition.
-  Cond = UsualUnaryConversions(Cond.take());
+  Cond = UsualUnaryConversions(Cond.get());
   if (Cond.isInvalid())
     return QualType();
   if (checkCondition(*this, Cond.get()))
@@ -5708,34 +5815,34 @@
   // redefinition type if an attempt is made to access its fields.
   if (LHSTy->isObjCClassType() &&
       (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
-    RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast);
+    RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_CPointerToObjCPointerCast);
     return LHSTy;
   }
   if (RHSTy->isObjCClassType() &&
       (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
-    LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast);
+    LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_CPointerToObjCPointerCast);
     return RHSTy;
   }
   // And the same for struct objc_object* / id
   if (LHSTy->isObjCIdType() &&
       (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
-    RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast);
+    RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_CPointerToObjCPointerCast);
     return LHSTy;
   }
   if (RHSTy->isObjCIdType() &&
       (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
-    LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast);
+    LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_CPointerToObjCPointerCast);
     return RHSTy;
   }
   // And the same for struct objc_selector* / SEL
   if (Context.isObjCSelType(LHSTy) &&
       (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
-    RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast);
     return LHSTy;
   }
   if (Context.isObjCSelType(RHSTy) &&
       (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
-    LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_BitCast);
+    LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast);
     return RHSTy;
   }
   // Check constraints for Objective-C object pointers types.
@@ -5784,13 +5891,13 @@
       << LHSTy << RHSTy
       << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
       QualType incompatTy = Context.getObjCIdType();
-      LHS = ImpCastExprToType(LHS.take(), incompatTy, CK_BitCast);
-      RHS = ImpCastExprToType(RHS.take(), incompatTy, CK_BitCast);
+      LHS = ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
+      RHS = ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
       return incompatTy;
     }
     // The object pointer types are compatible.
-    LHS = ImpCastExprToType(LHS.take(), compositeType, CK_BitCast);
-    RHS = ImpCastExprToType(RHS.take(), compositeType, CK_BitCast);
+    LHS = ImpCastExprToType(LHS.get(), compositeType, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), compositeType, CK_BitCast);
     return compositeType;
   }
   // Check Objective-C object pointer types and 'void *'
@@ -5809,9 +5916,9 @@
     = Context.getQualifiedType(lhptee, rhptee.getQualifiers());
     QualType destType = Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    LHS = ImpCastExprToType(LHS.take(), destType, CK_NoOp);
+    LHS = ImpCastExprToType(LHS.get(), destType, CK_NoOp);
     // Promote to void*.
-    RHS = ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), destType, CK_BitCast);
     return destType;
   }
   if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
@@ -5829,9 +5936,9 @@
     = Context.getQualifiedType(rhptee, lhptee.getQualifiers());
     QualType destType = Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    RHS = ImpCastExprToType(RHS.take(), destType, CK_NoOp);
+    RHS = ImpCastExprToType(RHS.get(), destType, CK_NoOp);
     // Promote to void*.
-    LHS = ImpCastExprToType(LHS.take(), destType, CK_BitCast);
+    LHS = ImpCastExprToType(LHS.get(), destType, CK_BitCast);
     return destType;
   }
   return QualType();
@@ -5973,7 +6080,7 @@
     if (commonExpr->hasPlaceholderType()) {
       ExprResult result = CheckPlaceholderExpr(commonExpr);
       if (!result.isUsable()) return ExprError();
-      commonExpr = result.take();
+      commonExpr = result.get();
     }
     // We usually want to apply unary conversions *before* saving, except
     // in the special case of a C++ l-value conditional.
@@ -5987,7 +6094,7 @@
       ExprResult commonRes = UsualUnaryConversions(commonExpr);
       if (commonRes.isInvalid())
         return ExprError();
-      commonExpr = commonRes.take();
+      commonExpr = commonRes.get();
     }
 
     opaqueValue = new (Context) OpaqueValueExpr(commonExpr->getExprLoc(),
@@ -6000,7 +6107,7 @@
 
   ExprValueKind VK = VK_RValue;
   ExprObjectKind OK = OK_Ordinary;
-  ExprResult Cond = Owned(CondExpr), LHS = Owned(LHSExpr), RHS = Owned(RHSExpr);
+  ExprResult Cond = CondExpr, LHS = LHSExpr, RHS = RHSExpr;
   QualType result = CheckConditionalOperands(Cond, LHS, RHS, 
                                              VK, OK, QuestionLoc);
   if (result.isNull() || Cond.isInvalid() || LHS.isInvalid() ||
@@ -6011,14 +6118,13 @@
                                 RHS.get());
 
   if (!commonExpr)
-    return Owned(new (Context) ConditionalOperator(Cond.take(), QuestionLoc,
-                                                   LHS.take(), ColonLoc, 
-                                                   RHS.take(), result, VK, OK));
+    return new (Context)
+        ConditionalOperator(Cond.get(), QuestionLoc, LHS.get(), ColonLoc,
+                            RHS.get(), result, VK, OK);
 
-  return Owned(new (Context)
-    BinaryConditionalOperator(commonExpr, opaqueValue, Cond.take(), LHS.take(),
-                              RHS.take(), QuestionLoc, ColonLoc, result, VK,
-                              OK));
+  return new (Context) BinaryConditionalOperator(
+      commonExpr, opaqueValue, Cond.get(), LHS.get(), RHS.get(), QuestionLoc,
+      ColonLoc, result, VK, OK);
 }
 
 // checkPointerTypesForAssignment - This is a very tricky routine (despite
@@ -6270,7 +6376,7 @@
     if (result != Compatible)
       return result;
     if (Kind != CK_NoOp)
-      RHS = ImpCastExprToType(RHS.take(), AtomicTy->getValueType(), Kind);
+      RHS = ImpCastExprToType(RHS.get(), AtomicTy->getValueType(), Kind);
     Kind = CK_NonAtomicToAtomic;
     return Compatible;
   }
@@ -6301,7 +6407,7 @@
       QualType elType = cast<ExtVectorType>(LHSType)->getElementType();
       if (elType != RHSType) {
         Kind = PrepareScalarCast(RHS, elType);
-        RHS = ImpCastExprToType(RHS.take(), elType, Kind);
+        RHS = ImpCastExprToType(RHS.get(), elType, Kind);
       }
       Kind = CK_VectorSplat;
       return Compatible;
@@ -6452,8 +6558,9 @@
       return IncompatiblePointer;
     }
 
-    // T^ -> A*
-    if (RHSType->isBlockPointerType()) {
+    // Only under strict condition T^ is compatible with an Objective-C pointer.
+    if (RHSType->isBlockPointerType() &&
+        isObjCPtrBlockCompatible(*this, Context, LHSType)) {
       maybeExtendBlockObject(*this, RHS);
       Kind = CK_BlockPointerToObjCPointerCast;
       return Compatible;
@@ -6514,7 +6621,7 @@
                                       FieldDecl *Field) {
   // Build an initializer list that designates the appropriate member
   // of the transparent union.
-  Expr *E = EResult.take();
+  Expr *E = EResult.get();
   InitListExpr *Initializer = new (C) InitListExpr(C, SourceLocation(),
                                                    E, SourceLocation());
   Initializer->setType(UnionType);
@@ -6523,9 +6630,8 @@
   // Build a compound literal constructing a value of the transparent
   // union type from this initializer list.
   TypeSourceInfo *unionTInfo = C.getTrivialTypeSourceInfo(UnionType);
-  EResult = S.Owned(
-    new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType,
-                                VK_RValue, Initializer, false));
+  EResult = new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType,
+                                        VK_RValue, Initializer, false);
 }
 
 Sema::AssignConvertType
@@ -6550,14 +6656,14 @@
       // 2) null pointer constant
       if (RHSType->isPointerType())
         if (RHSType->castAs<PointerType>()->getPointeeType()->isVoidType()) {
-          RHS = ImpCastExprToType(RHS.take(), it->getType(), CK_BitCast);
+          RHS = ImpCastExprToType(RHS.get(), it->getType(), CK_BitCast);
           InitField = it;
           break;
         }
 
       if (RHS.get()->isNullPointerConstant(Context,
                                            Expr::NPC_ValueDependentIsNull)) {
-        RHS = ImpCastExprToType(RHS.take(), it->getType(),
+        RHS = ImpCastExprToType(RHS.get(), it->getType(),
                                 CK_NullToPointer);
         InitField = it;
         break;
@@ -6567,7 +6673,7 @@
     CastKind Kind = CK_Invalid;
     if (CheckAssignmentConstraints(it->getType(), RHS, Kind)
           == Compatible) {
-      RHS = ImpCastExprToType(RHS.take(), it->getType(), Kind);
+      RHS = ImpCastExprToType(RHS.get(), it->getType(), Kind);
       InitField = it;
       break;
     }
@@ -6632,7 +6738,7 @@
     CastKind Kind;
     CXXCastPath Path;
     CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false);
-    RHS = ImpCastExprToType(RHS.take(), LHSType, Kind, VK_RValue, &Path);
+    RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
     return Compatible;
   }
 
@@ -6643,7 +6749,7 @@
   //
   // Suppress this for references: C++ 8.5.3p5.
   if (!LHSType->isReferenceType()) {
-    RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+    RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
     if (RHS.isInvalid())
       return Incompatible;
   }
@@ -6660,7 +6766,7 @@
   // does not have reference type.
   if (result != Incompatible && RHS.get()->getType() != LHSType) {
     QualType Ty = LHSType.getNonLValueExprType(Context);
-    Expr *E = RHS.take();
+    Expr *E = RHS.get();
     if (getLangOpts().ObjCAutoRefCount)
       CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
                              DiagnoseCFAudited);
@@ -6668,7 +6774,7 @@
         (CheckObjCBridgeRelatedConversions(E->getLocStart(),
                                           LHSType, E->getType(), E) ||
          ConversionToObjCStringLiteralCheck(LHSType, E))) {
-      RHS = Owned(E);
+      RHS = E;
       return Compatible;
     }
     
@@ -6726,8 +6832,8 @@
   // Adjust scalar if desired.
   if (scalar) {
     if (scalarCast != CK_Invalid)
-      *scalar = S.ImpCastExprToType(scalar->take(), vectorEltTy, scalarCast);
-    *scalar = S.ImpCastExprToType(scalar->take(), vectorTy, CK_VectorSplat);
+      *scalar = S.ImpCastExprToType(scalar->get(), vectorEltTy, scalarCast);
+    *scalar = S.ImpCastExprToType(scalar->get(), vectorTy, CK_VectorSplat);
   }
   return false;
 }
@@ -6735,11 +6841,11 @@
 QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
                                    SourceLocation Loc, bool IsCompAssign) {
   if (!IsCompAssign) {
-    LHS = DefaultFunctionArrayLvalueConversion(LHS.take());
+    LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
     if (LHS.isInvalid())
       return QualType();
   }
-  RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+  RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
   if (RHS.isInvalid())
     return QualType();
 
@@ -6760,12 +6866,12 @@
   if (LHSVecType && RHSVecType &&
       Context.areCompatibleVectorTypes(LHSType, RHSType)) {
     if (isa<ExtVectorType>(LHSVecType)) {
-      RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+      RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
       return LHSType;
     }
 
     if (!IsCompAssign)
-      LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+      LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast);
     return RHSType;
   }
 
@@ -6789,7 +6895,7 @@
   // FIXME: We really just pick the LHS type arbitrarily?
   if (isLaxVectorConversion(RHSType, LHSType)) {
     QualType resultType = LHSType;
-    RHS = ImpCastExprToType(RHS.take(), resultType, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), resultType, CK_BitCast);
     return resultType;
   }
 
@@ -7402,14 +7508,14 @@
   // For the LHS, do usual unary conversions, but then reset them away
   // if this is a compound assignment.
   ExprResult OldLHS = LHS;
-  LHS = UsualUnaryConversions(LHS.take());
+  LHS = UsualUnaryConversions(LHS.get());
   if (LHS.isInvalid())
     return QualType();
   QualType LHSType = LHS.get()->getType();
   if (IsCompAssign) LHS = OldLHS;
 
   // The RHS is simpler.
-  RHS = UsualUnaryConversions(RHS.take());
+  RHS = UsualUnaryConversions(RHS.get());
   if (RHS.isInvalid())
     return QualType();
   QualType RHSType = RHS.get()->getType();
@@ -7521,8 +7627,8 @@
       << LHSType << RHSType << T << LHS.get()->getSourceRange()
       << RHS.get()->getSourceRange();
 
-  LHS = S.ImpCastExprToType(LHS.take(), T, CK_BitCast);
-  RHS = S.ImpCastExprToType(RHS.take(), T, CK_BitCast);
+  LHS = S.ImpCastExprToType(LHS.get(), T, CK_BitCast);
+  RHS = S.ImpCastExprToType(RHS.get(), T, CK_BitCast);
   return false;
 }
 
@@ -7588,7 +7694,7 @@
   if (!Method)
     return false;
 
-  QualType T = Method->param_begin()[0]->getType();
+  QualType T = Method->parameters()[0]->getType();
   if (!T->isObjCObjectPointerType())
     return false;
 
@@ -7911,7 +8017,7 @@
           if (isSFINAEContext())
             return QualType();
           
-          RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+          RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
           return ResultTy;
         }
       }
@@ -7947,9 +8053,9 @@
       CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion
                                                : CK_BitCast;
       if (LHSIsNull && !RHSIsNull)
-        LHS = ImpCastExprToType(LHS.take(), RHSType, Kind);
+        LHS = ImpCastExprToType(LHS.get(), RHSType, Kind);
       else
-        RHS = ImpCastExprToType(RHS.take(), LHSType, Kind);
+        RHS = ImpCastExprToType(RHS.get(), LHSType, Kind);
     }
     return ResultTy;
   }
@@ -7965,7 +8071,7 @@
         ((LHSType->isAnyPointerType() || LHSType->isNullPtrType()) ||
          (!IsRelational && 
           (LHSType->isMemberPointerType() || LHSType->isBlockPointerType())))) {
-      RHS = ImpCastExprToType(RHS.take(), LHSType, 
+      RHS = ImpCastExprToType(RHS.get(), LHSType, 
                         LHSType->isMemberPointerType()
                           ? CK_NullToMemberPointer
                           : CK_NullToPointer);
@@ -7975,7 +8081,7 @@
         ((RHSType->isAnyPointerType() || RHSType->isNullPtrType()) ||
          (!IsRelational && 
           (RHSType->isMemberPointerType() || RHSType->isBlockPointerType())))) {
-      LHS = ImpCastExprToType(LHS.take(), RHSType, 
+      LHS = ImpCastExprToType(LHS.get(), RHSType, 
                         RHSType->isMemberPointerType()
                           ? CK_NullToMemberPointer
                           : CK_NullToPointer);
@@ -8011,7 +8117,7 @@
         << LHSType << RHSType << LHS.get()->getSourceRange()
         << RHS.get()->getSourceRange();
     }
-    RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
     return ResultTy;
   }
 
@@ -8029,11 +8135,11 @@
           << RHS.get()->getSourceRange();
     }
     if (LHSIsNull && !RHSIsNull)
-      LHS = ImpCastExprToType(LHS.take(), RHSType,
+      LHS = ImpCastExprToType(LHS.get(), RHSType,
                               RHSType->isPointerType() ? CK_BitCast
                                 : CK_AnyPointerToBlockPointerCast);
     else
-      RHS = ImpCastExprToType(RHS.take(), LHSType,
+      RHS = ImpCastExprToType(RHS.get(), LHSType,
                               LHSType->isPointerType() ? CK_BitCast
                                 : CK_AnyPointerToBlockPointerCast);
     return ResultTy;
@@ -8053,16 +8159,17 @@
                                           /*isError*/false);
       }
       if (LHSIsNull && !RHSIsNull) {
-        Expr *E = LHS.take();
+        Expr *E = LHS.get();
         if (getLangOpts().ObjCAutoRefCount)
           CheckObjCARCConversion(SourceRange(), RHSType, E, CCK_ImplicitConversion);
         LHS = ImpCastExprToType(E, RHSType,
                                 RPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
       }
       else {
-        Expr *E = RHS.take();
+        Expr *E = RHS.get();
         if (getLangOpts().ObjCAutoRefCount)
-          CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion);
+          CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion, false,
+                                 Opc);
         RHS = ImpCastExprToType(E, LHSType,
                                 LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
       }
@@ -8077,9 +8184,9 @@
         diagnoseObjCLiteralComparison(*this, Loc, LHS, RHS, Opc);
 
       if (LHSIsNull && !RHSIsNull)
-        LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+        LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast);
       else
-        RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+        RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
       return ResultTy;
     }
   }
@@ -8111,10 +8218,10 @@
     }
     
     if (LHSType->isIntegerType())
-      LHS = ImpCastExprToType(LHS.take(), RHSType,
+      LHS = ImpCastExprToType(LHS.get(), RHSType,
                         LHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
     else
-      RHS = ImpCastExprToType(RHS.take(), LHSType,
+      RHS = ImpCastExprToType(RHS.get(), LHSType,
                         RHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
     return ResultTy;
   }
@@ -8122,12 +8229,12 @@
   // Handle block pointers.
   if (!IsRelational && RHSIsNull
       && LHSType->isBlockPointerType() && RHSType->isIntegerType()) {
-    RHS = ImpCastExprToType(RHS.take(), LHSType, CK_NullToPointer);
+    RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
     return ResultTy;
   }
   if (!IsRelational && LHSIsNull
       && LHSType->isIntegerType() && RHSType->isBlockPointerType()) {
-    LHS = ImpCastExprToType(LHS.take(), RHSType, CK_NullToPointer);
+    LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
     return ResultTy;
   }
 
@@ -8228,13 +8335,13 @@
     return InvalidOperands(Loc, LHS, RHS);
   }
 
-  ExprResult LHSResult = Owned(LHS), RHSResult = Owned(RHS);
+  ExprResult LHSResult = LHS, RHSResult = RHS;
   QualType compType = UsualArithmeticConversions(LHSResult, RHSResult,
                                                  IsCompAssign);
   if (LHSResult.isInvalid() || RHSResult.isInvalid())
     return QualType();
-  LHS = LHSResult.take();
-  RHS = RHSResult.take();
+  LHS = LHSResult.get();
+  RHS = RHSResult.get();
 
   if (!compType.isNull() && compType->isIntegralOrUnscopedEnumerationType())
     return compType;
@@ -8297,11 +8404,11 @@
         return InvalidOperands(Loc, LHS, RHS);
     }
 
-    LHS = UsualUnaryConversions(LHS.take());
+    LHS = UsualUnaryConversions(LHS.get());
     if (LHS.isInvalid())
       return QualType();
 
-    RHS = UsualUnaryConversions(RHS.take());
+    RHS = UsualUnaryConversions(RHS.get());
     if (RHS.isInvalid())
       return QualType();
 
@@ -8581,10 +8688,8 @@
         // we do not warn to warn spuriously when 'x' and 'y' are on separate
         // paths through the function. This should be revisited if
         // -Wrepeated-use-of-weak is made flow-sensitive.
-        DiagnosticsEngine::Level Level =
-          Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                   RHS.get()->getLocStart());
-        if (Level != DiagnosticsEngine::Ignored)
+        if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+                             RHS.get()->getLocStart()))
           getCurFunction()->markSafeWeakUse(RHS.get());
 
       } else if (getLangOpts().ObjCAutoRefCount) {
@@ -8616,8 +8721,8 @@
 // C99 6.5.17
 static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,
                                    SourceLocation Loc) {
-  LHS = S.CheckPlaceholderExpr(LHS.take());
-  RHS = S.CheckPlaceholderExpr(RHS.take());
+  LHS = S.CheckPlaceholderExpr(LHS.get());
+  RHS = S.CheckPlaceholderExpr(RHS.get());
   if (LHS.isInvalid() || RHS.isInvalid())
     return QualType();
 
@@ -8627,14 +8732,14 @@
 
   // So we treat the LHS as a ignored value, and in C++ we allow the
   // containing site to determine what should be done with the RHS.
-  LHS = S.IgnoredValueConversions(LHS.take());
+  LHS = S.IgnoredValueConversions(LHS.get());
   if (LHS.isInvalid())
     return QualType();
 
   S.DiagnoseUnusedExprResult(LHS.get());
 
   if (!S.getLangOpts().CPlusPlus) {
-    RHS = S.DefaultFunctionArrayLvalueConversion(RHS.take());
+    RHS = S.DefaultFunctionArrayLvalueConversion(RHS.get());
     if (RHS.isInvalid())
       return QualType();
     if (!RHS.get()->getType()->isVoidType())
@@ -8694,7 +8799,7 @@
   } else if (ResType->isPlaceholderType()) {
     ExprResult PR = S.CheckPlaceholderExpr(Op);
     if (PR.isInvalid()) return QualType();
-    return CheckIncrementDecrementOperand(S, PR.take(), VK, OpLoc,
+    return CheckIncrementDecrementOperand(S, PR.get(), VK, OpLoc,
                                           IsInc, IsPrefix);
   } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) {
     // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 )
@@ -8835,7 +8940,7 @@
       return QualType();
     }
 
-    OrigOp = CheckPlaceholderExpr(OrigOp.take());
+    OrigOp = CheckPlaceholderExpr(OrigOp.get());
     if (OrigOp.isInvalid()) return QualType();
   }
 
@@ -8877,7 +8982,7 @@
       return QualType();
     // Materialize the temporary as an lvalue so that we can take its address.
     OrigOp = op = new (Context)
-        MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true);
+        MaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
   } else if (isa<ObjCSelectorExpr>(op)) {
     return Context.getPointerType(op->getType());
   } else if (lval == Expr::LV_MemberFunction) {
@@ -9008,7 +9113,7 @@
   ExprResult ConvResult = S.UsualUnaryConversions(Op);
   if (ConvResult.isInvalid())
     return QualType();
-  Op = ConvResult.take();
+  Op = ConvResult.get();
   QualType OpTy = Op->getType();
   QualType Result;
 
@@ -9026,8 +9131,8 @@
   else {
     ExprResult PR = S.CheckPlaceholderExpr(Op);
     if (PR.isInvalid()) return QualType();
-    if (PR.take() != Op)
-      return CheckIndirectionOperand(S, PR.take(), VK, OpLoc);
+    if (PR.get() != Op)
+      return CheckIndirectionOperand(S, PR.get(), VK, OpLoc);
   }
 
   if (Result.isNull()) {
@@ -9218,10 +9323,10 @@
     ExprResult Init = InitSeq.Perform(*this, Entity, Kind, RHSExpr);
     if (Init.isInvalid())
       return Init;
-    RHSExpr = Init.take();
+    RHSExpr = Init.get();
   }
 
-  ExprResult LHS = Owned(LHSExpr), RHS = Owned(RHSExpr);
+  ExprResult LHS = LHSExpr, RHS = RHSExpr;
   QualType ResultTy;     // Result type of the binary operator.
   // The following two variables are used for compound assignment operators
   QualType CompLHSTy;    // Type of LHS after promotions for computation
@@ -9315,8 +9420,9 @@
       ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy);
     break;
   case BO_AndAssign:
+  case BO_OrAssign: // fallthrough
+	  DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc);
   case BO_XorAssign:
-  case BO_OrAssign:
     CompResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, true);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull() && !LHS.isInvalid() && !RHS.isInvalid())
@@ -9356,18 +9462,16 @@
     DiagnoseDirectIsaAccess(*this, OIRE, OpLoc, RHS.get());
   
   if (CompResultTy.isNull())
-    return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc,
-                                              ResultTy, VK, OK, OpLoc,
-                                              FPFeatures.fp_contract));
+    return new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, ResultTy, VK,
+                                        OK, OpLoc, FPFeatures.fp_contract);
   if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() !=
       OK_ObjCProperty) {
     VK = VK_LValue;
     OK = LHS.get()->getObjectKind();
   }
-  return Owned(new (Context) CompoundAssignOperator(LHS.take(), RHS.take(), Opc,
-                                                    ResultTy, VK, OK, CompLHSTy,
-                                                    CompResultTy, OpLoc,
-                                                    FPFeatures.fp_contract));
+  return new (Context) CompoundAssignOperator(
+      LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, CompLHSTy, CompResultTy,
+      OpLoc, FPFeatures.fp_contract);
 }
 
 /// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
@@ -9639,7 +9743,7 @@
       // instantiates to having an overloadable type.
       ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
       if (resolvedRHS.isInvalid()) return ExprError();
-      RHSExpr = resolvedRHS.take();
+      RHSExpr = resolvedRHS.get();
 
       if (RHSExpr->isTypeDependent() ||
           RHSExpr->getType()->isOverloadableType())
@@ -9648,7 +9752,7 @@
         
     ExprResult LHS = CheckPlaceholderExpr(LHSExpr);
     if (LHS.isInvalid()) return ExprError();
-    LHSExpr = LHS.take();
+    LHSExpr = LHS.get();
   }
 
   // Handle pseudo-objects in the RHS.
@@ -9672,7 +9776,7 @@
 
     ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
     if (!resolvedRHS.isUsable()) return ExprError();
-    RHSExpr = resolvedRHS.take();
+    RHSExpr = resolvedRHS.get();
   }
 
   if (getLangOpts().CPlusPlus) {
@@ -9695,7 +9799,7 @@
 ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
                                       UnaryOperatorKind Opc,
                                       Expr *InputExpr) {
-  ExprResult Input = Owned(InputExpr);
+  ExprResult Input = InputExpr;
   ExprValueKind VK = VK_RValue;
   ExprObjectKind OK = OK_Ordinary;
   QualType resultType;
@@ -9714,14 +9818,14 @@
     resultType = CheckAddressOfOperand(Input, OpLoc);
     break;
   case UO_Deref: {
-    Input = DefaultFunctionArrayLvalueConversion(Input.take());
+    Input = DefaultFunctionArrayLvalueConversion(Input.get());
     if (Input.isInvalid()) return ExprError();
     resultType = CheckIndirectionOperand(*this, Input.get(), VK, OpLoc);
     break;
   }
   case UO_Plus:
   case UO_Minus:
-    Input = UsualUnaryConversions(Input.take());
+    Input = UsualUnaryConversions(Input.get());
     if (Input.isInvalid()) return ExprError();
     resultType = Input.get()->getType();
     if (resultType->isDependentType())
@@ -9738,7 +9842,7 @@
       << resultType << Input.get()->getSourceRange());
 
   case UO_Not: // bitwise complement
-    Input = UsualUnaryConversions(Input.take());
+    Input = UsualUnaryConversions(Input.get());
     if (Input.isInvalid())
       return ExprError();
     resultType = Input.get()->getType();
@@ -9769,13 +9873,13 @@
 
   case UO_LNot: // logical negation
     // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
-    Input = DefaultFunctionArrayLvalueConversion(Input.take());
+    Input = DefaultFunctionArrayLvalueConversion(Input.get());
     if (Input.isInvalid()) return ExprError();
     resultType = Input.get()->getType();
 
     // Though we still have to promote half FP to float...
     if (resultType->isHalfType() && !Context.getLangOpts().NativeHalfType) {
-      Input = ImpCastExprToType(Input.take(), Context.FloatTy, CK_FloatingCast).take();
+      Input = ImpCastExprToType(Input.get(), Context.FloatTy, CK_FloatingCast).get();
       resultType = Context.FloatTy;
     }
 
@@ -9786,7 +9890,7 @@
       if (Context.getLangOpts().CPlusPlus) {
         // C++03 [expr.unary.op]p8, C++0x [expr.unary.op]p9:
         // operand contextually converted to bool.
-        Input = ImpCastExprToType(Input.take(), Context.BoolTy,
+        Input = ImpCastExprToType(Input.get(), Context.BoolTy,
                                   ScalarTypeToBooleanCastKind(resultType));
       } else if (Context.getLangOpts().OpenCL &&
                  Context.getLangOpts().OpenCLVersion < 120) {
@@ -9830,7 +9934,7 @@
         VK = Input.get()->getValueKind();
     } else if (!getLangOpts().CPlusPlus) {
       // In C, a volatile scalar is read by __imag. In C++, it is not.
-      Input = DefaultLvalueConversion(Input.take());
+      Input = DefaultLvalueConversion(Input.get());
     }
     break;
   case UO_Extension:
@@ -9849,8 +9953,8 @@
   if (Opc != UO_AddrOf && Opc != UO_Deref)
     CheckArrayAccess(Input.get());
 
-  return Owned(new (Context) UnaryOperator(Input.take(), Opc, resultType,
-                                           VK, OK, OpLoc));
+  return new (Context)
+      UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc);
 }
 
 /// \brief Determine whether the given expression is a qualified member
@@ -9920,7 +10024,7 @@
     // Anything else needs to be handled now.
     ExprResult Result = CheckPlaceholderExpr(Input);
     if (Result.isInvalid()) return ExprError();
-    Input = Result.take();
+    Input = Result.get();
   }
 
   if (getLangOpts().CPlusPlus && Input->getType()->isOverloadableType() &&
@@ -9953,8 +10057,8 @@
                                 LabelDecl *TheDecl) {
   TheDecl->markUsed(Context);
   // Create the AST node.  The address of a label always has type 'void*'.
-  return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
-                                       Context.getPointerType(Context.VoidTy)));
+  return new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
+                                     Context.getPointerType(Context.VoidTy));
 }
 
 /// Given the last statement in a statement-expression, check whether
@@ -10056,9 +10160,9 @@
           return ExprError();
         if (LastExpr.get() != nullptr) {
           if (!LastLabelStmt)
-            Compound->setLastStmt(LastExpr.take());
+            Compound->setLastStmt(LastExpr.get());
           else
-            LastLabelStmt->setSubStmt(LastExpr.take());
+            LastLabelStmt->setSubStmt(LastExpr.get());
           StmtExprMayBindToTemp = true;
         }
       }
@@ -10070,7 +10174,7 @@
   Expr *ResStmtExpr = new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc);
   if (StmtExprMayBindToTemp)
     return MaybeBindToTemporary(ResStmtExpr);
-  return Owned(ResStmtExpr);
+  return ResStmtExpr;
 }
 
 ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
@@ -10125,7 +10229,7 @@
       ExprResult IdxRval = DefaultLvalueConversion(static_cast<Expr*>(OC.U.E));
       if (IdxRval.isInvalid())
         return ExprError();
-      Expr *Idx = IdxRval.take();
+      Expr *Idx = IdxRval.get();
 
       // The expression must be an integral expression.
       // FIXME: An integral constant expression?
@@ -10243,8 +10347,8 @@
     CurrentType = MemberDecl->getType().getNonReferenceType(); 
   }
   
-  return Owned(OffsetOfExpr::Create(Context, Context.getSizeType(), BuiltinLoc, 
-                                    TInfo, Comps, Exprs, RParenLoc));
+  return OffsetOfExpr::Create(Context, Context.getSizeType(), BuiltinLoc, TInfo,
+                              Comps, Exprs, RParenLoc);
 }
 
 ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
@@ -10290,7 +10394,7 @@
           diag::err_typecheck_choose_expr_requires_constant, false);
     if (CondICE.isInvalid())
       return ExprError();
-    CondExpr = CondICE.take();
+    CondExpr = CondICE.get();
     CondIsTrue = condEval.getZExtValue();
 
     // If the condition is > zero, then the AST type is the same as the LSHExpr.
@@ -10302,10 +10406,9 @@
     OK = ActiveExpr->getObjectKind();
   }
 
-  return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
-                                        resType, VK, OK, RPLoc, CondIsTrue,
-                                        resType->isDependentType(),
-                                        ValueDependent));
+  return new (Context)
+      ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, VK, OK, RPLoc,
+                 CondIsTrue, resType->isDependentType(), ValueDependent);
 }
 
 //===----------------------------------------------------------------------===//
@@ -10585,7 +10688,7 @@
     }
   }
 
-  return Owned(Result);
+  return Result;
 }
 
 ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
@@ -10612,7 +10715,7 @@
     ExprResult Result = UsualUnaryConversions(E);
     if (Result.isInvalid())
       return ExprError();
-    E = Result.take();
+    E = Result.get();
   } else if (VaListType->isRecordType() && getLangOpts().CPlusPlus) {
     // If va_list is a record type and we are compiling in C++ mode,
     // check the argument using reference binding.
@@ -10622,7 +10725,7 @@
     ExprResult Init = PerformCopyInitialization(Entity, SourceLocation(), E);
     if (Init.isInvalid())
       return ExprError();
-    E = Init.takeAs<Expr>();
+    E = Init.getAs<Expr>();
   } else {
     // Otherwise, the va_list argument must be an l-value because
     // it is modified by va_arg.
@@ -10678,7 +10781,7 @@
   }
 
   QualType T = TInfo->getType().getNonLValueExprType(Context);
-  return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
+  return new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T);
 }
 
 ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
@@ -10696,7 +10799,7 @@
     llvm_unreachable("I don't know size of pointer!");
   }
 
-  return Owned(new (Context) GNUNullExpr(Ty, TokenLoc));
+  return new (Context) GNUNullExpr(Ty, TokenLoc);
 }
 
 bool
@@ -10728,7 +10831,7 @@
     return false;
   Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
     << FixItHint::CreateInsertion(SL->getLocStart(), "@");
-  Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).take();
+  Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
   return true;
 }
 
@@ -10748,6 +10851,8 @@
   ConversionFixItGenerator ConvHints;
   bool MayHaveConvFixit = false;
   bool MayHaveFunctionDiff = false;
+  const ObjCInterfaceDecl *IFace = nullptr;
+  const ObjCProtocolDecl *PDecl = nullptr;
 
   switch (ConvTy) {
   case Compatible:
@@ -10829,11 +10934,32 @@
   case IncompatibleBlockPointer:
     DiagKind = diag::err_typecheck_convert_incompatible_block_pointer;
     break;
-  case IncompatibleObjCQualifiedId:
-    // FIXME: Diagnose the problem in ObjCQualifiedIdTypesAreCompatible, since
-    // it can give a more specific diagnostic.
+  case IncompatibleObjCQualifiedId: {
+    if (SrcType->isObjCQualifiedIdType()) {
+      const ObjCObjectPointerType *srcOPT =
+                SrcType->getAs<ObjCObjectPointerType>();
+      for (auto *srcProto : srcOPT->quals()) {
+        PDecl = srcProto;
+        break;
+      }
+      if (const ObjCInterfaceType *IFaceT =
+            DstType->getAs<ObjCObjectPointerType>()->getInterfaceType())
+        IFace = IFaceT->getDecl();
+    }
+    else if (DstType->isObjCQualifiedIdType()) {
+      const ObjCObjectPointerType *dstOPT =
+        DstType->getAs<ObjCObjectPointerType>();
+      for (auto *dstProto : dstOPT->quals()) {
+        PDecl = dstProto;
+        break;
+      }
+      if (const ObjCInterfaceType *IFaceT =
+            SrcType->getAs<ObjCObjectPointerType>()->getInterfaceType())
+        IFace = IFaceT->getDecl();
+    }
     DiagKind = diag::warn_incompatible_qualified_id;
     break;
+  }
   case IncompatibleVectors:
     DiagKind = diag::warn_incompatible_vectors;
     break;
@@ -10891,7 +11017,11 @@
     HandleFunctionTypeMismatch(FDiag, SecondType, FirstType);
 
   Diag(Loc, FDiag);
-
+  if (DiagKind == diag::warn_incompatible_qualified_id &&
+      PDecl && IFace && !IFace->hasDefinition())
+      Diag(IFace->getLocation(), diag::not_incomplete_class_and_qualified_id)
+        << IFace->getName() << PDecl->getName();
+    
   if (SecondType == Context.OverloadTy)
     NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression,
                               FirstType);
@@ -11004,7 +11134,7 @@
                                                     ConvertDiagnoser);
     if (Converted.isInvalid())
       return Converted;
-    E = Converted.take();
+    E = Converted.get();
     if (!E->getType()->isIntegralOrUnscopedEnumerationType())
       return ExprError();
   } else if (!E->getType()->isIntegralOrUnscopedEnumerationType()) {
@@ -11019,7 +11149,7 @@
   if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
     if (Result)
       *Result = E->EvaluateKnownConstInt(Context);
-    return Owned(E);
+    return E;
   }
 
   Expr::EvalResult EvalResult;
@@ -11037,7 +11167,7 @@
   if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) {
     if (Result)
       *Result = EvalResult.Val.getInt();
-    return Owned(E);
+    return E;
   }
 
   // If our only note is the usual "invalid subexpression" note, just point
@@ -11065,7 +11195,7 @@
 
   if (Result)
     *Result = EvalResult.Val.getInt();
-  return Owned(E);
+  return E;
 }
 
 namespace {
@@ -11304,7 +11434,7 @@
     Constructor = cast<CXXConstructorDecl>(Constructor->getFirstDecl());
     if (Constructor->isDefaulted() && !Constructor->isDeleted()) {
       if (Constructor->isDefaultConstructor()) {
-        if (Constructor->isTrivial())
+        if (Constructor->isTrivial() && !Constructor->hasAttr<DLLExportAttr>())
           return;
         DefineImplicitDefaultConstructor(Loc, Constructor);
       } else if (Constructor->isCopyConstructor()) {
@@ -11469,8 +11599,8 @@
       << var->getIdentifier();
   }
 
-  S.Diag(var->getLocation(), diag::note_local_variable_declared_here)
-    << var->getIdentifier();
+  S.Diag(var->getLocation(), diag::note_entity_declared_at)
+      << var->getIdentifier();
 
   // FIXME: Add additional diagnostic info about class etc. which prevents
   // capture.
@@ -11538,7 +11668,7 @@
   }
 
   // Prohibit variably-modified types; they're difficult to deal with.
-  if (Var->getType()->isVariablyModifiedType()) {
+  if (Var->getType()->isVariablyModifiedType() && (IsBlock || IsLambda)) {
     if (Diagnose) {
       if (IsBlock)
         S.Diag(Loc, diag::err_ref_vm_type);
@@ -11647,7 +11777,7 @@
           = S.PerformCopyInitialization(
               InitializedEntity::InitializeBlock(Var->getLocation(),
                                                   CaptureType, false),
-              Loc, S.Owned(DeclRef));
+              Loc, DeclRef);
             
         // Build a full-expression copy expression if initialization
         // succeeded and used a non-trivial constructor.  Recover from
@@ -11656,7 +11786,7 @@
             !cast<CXXConstructExpr>(Result.get())->getConstructor()
                 ->isTrivial()) {
           Result = S.MaybeCreateExprWithCleanups(Result);
-          CopyExpr = Result.take();
+          CopyExpr = Result.get();
         }
       }
     }
@@ -11788,20 +11918,20 @@
       = S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
     assert(!IterationVarRef.isInvalid() &&
            "Reference to invented variable cannot fail!");
-    IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.take());
+    IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.get());
     assert(!IterationVarRef.isInvalid() &&
            "Conversion of invented variable cannot fail!");
     
     // Subscript the array with this iteration variable.
     ExprResult Subscript = S.CreateBuiltinArraySubscriptExpr(
-                             Ref, Loc, IterationVarRef.take(), Loc);
+                             Ref, Loc, IterationVarRef.get(), Loc);
     if (Subscript.isInvalid()) {
       S.CleanupVarDeclMarking();
       S.DiscardCleanupsInEvaluationContext();
       return ExprError();
     }
 
-    Ref = Subscript.take();
+    Ref = Subscript.get();
     BaseType = Array->getElementType();
   }
 
@@ -11922,7 +12052,7 @@
                                         CaptureType, DeclRefType, Loc,
                                         RefersToEnclosingLocal);
     if (!Result.isInvalid())
-      CopyExpr = Result.take();
+      CopyExpr = Result.get();
   }
     
   // Compute the type of a reference to this captured variable.
@@ -12025,8 +12155,107 @@
     // certain types of variables (unnamed, variably modified types etc.)
     // so check for eligibility.
     if (!isVariableCapturable(CSI, Var, ExprLoc, BuildAndDiagnose, *this))
-       return true;    
-    
+       return true;
+
+    // Try to capture variable-length arrays types.
+    if (Var->getType()->isVariablyModifiedType()) {
+      // We're going to walk down into the type and look for VLA
+      // expressions.
+      QualType QTy = Var->getType();
+      if (ParmVarDecl *PVD = dyn_cast_or_null<ParmVarDecl>(Var))
+        QTy = PVD->getOriginalType();
+      do {
+        const Type *Ty = QTy.getTypePtr();
+        switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+          QTy = QualType();
+          break;
+        // These types are never variably-modified.
+        case Type::Builtin:
+        case Type::Complex:
+        case Type::Vector:
+        case Type::ExtVector:
+        case Type::Record:
+        case Type::Enum:
+        case Type::Elaborated:
+        case Type::TemplateSpecialization:
+        case Type::ObjCObject:
+        case Type::ObjCInterface:
+        case Type::ObjCObjectPointer:
+          llvm_unreachable("type class is never variably-modified!");
+        case Type::Adjusted:
+          QTy = cast<AdjustedType>(Ty)->getOriginalType();
+          break;
+        case Type::Decayed:
+          QTy = cast<DecayedType>(Ty)->getPointeeType();
+          break;
+        case Type::Pointer:
+          QTy = cast<PointerType>(Ty)->getPointeeType();
+          break;
+        case Type::BlockPointer:
+          QTy = cast<BlockPointerType>(Ty)->getPointeeType();
+          break;
+        case Type::LValueReference:
+        case Type::RValueReference:
+          QTy = cast<ReferenceType>(Ty)->getPointeeType();
+          break;
+        case Type::MemberPointer:
+          QTy = cast<MemberPointerType>(Ty)->getPointeeType();
+          break;
+        case Type::ConstantArray:
+        case Type::IncompleteArray:
+          // Losing element qualification here is fine.
+          QTy = cast<ArrayType>(Ty)->getElementType();
+          break;
+        case Type::VariableArray: {
+          // Losing element qualification here is fine.
+          const VariableArrayType *Vat = cast<VariableArrayType>(Ty);
+
+          // Unknown size indication requires no size computation.
+          // Otherwise, evaluate and record it.
+          if (Expr *Size = Vat->getSizeExpr()) {
+            MarkDeclarationsReferencedInExpr(Size);
+          }
+          QTy = Vat->getElementType();
+          break;
+        }
+        case Type::FunctionProto:
+        case Type::FunctionNoProto:
+          QTy = cast<FunctionType>(Ty)->getReturnType();
+          break;
+        case Type::Paren:
+        case Type::TypeOf:
+        case Type::UnaryTransform:
+        case Type::Attributed:
+        case Type::SubstTemplateTypeParm:
+        case Type::PackExpansion:
+          // Keep walking after single level desugaring.
+          QTy = QTy.getSingleStepDesugaredType(getASTContext());
+          break;
+        case Type::Typedef:
+          QTy = cast<TypedefType>(Ty)->desugar();
+          break;
+        case Type::Decltype:
+          QTy = cast<DecltypeType>(Ty)->desugar();
+          break;
+        case Type::Auto:
+          QTy = cast<AutoType>(Ty)->getDeducedType();
+          break;
+        case Type::TypeOfExpr:
+          QTy = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
+          break;
+        case Type::Atomic:
+          QTy = cast<AtomicType>(Ty)->getValueType();
+          break;
+        }
+      } while (!QTy.isNull() && QTy->isVariablyModifiedType());
+    }
+
     if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) {
       // No capture-default, and this is not an explicit capture 
       // so cannot capture this variable.  
@@ -12586,9 +12815,8 @@
       
       S.Diag(Loc, diag::err_call_function_incomplete_return)
         << CE->getSourceRange() << FD->getDeclName() << T;
-      S.Diag(FD->getLocation(),
-             diag::note_function_with_incomplete_return_type_declared_here)
-        << FD->getDeclName();
+      S.Diag(FD->getLocation(), diag::note_entity_declared_at)
+          << FD->getDeclName();
     }
   } Diagnoser(FD, CE);
   
@@ -12692,7 +12920,7 @@
 
   ExprResult result = CheckPlaceholderExpr(E);
   if (result.isInvalid()) return ExprError();
-  E = result.take();
+  E = result.get();
 
   if (!E->isTypeDependent()) {
     if (getLangOpts().CPlusPlus)
@@ -12701,7 +12929,7 @@
     ExprResult ERes = DefaultFunctionArrayLvalueConversion(E);
     if (ERes.isInvalid())
       return ExprError();
-    E = ERes.take();
+    E = ERes.get();
 
     QualType T = E->getType();
     if (!T->isScalarType()) { // C99 6.8.4.1p1
@@ -12711,7 +12939,7 @@
     }
   }
 
-  return Owned(E);
+  return E;
 }
 
 ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
@@ -12748,7 +12976,7 @@
       ExprResult SubResult = Visit(E->getSubExpr());
       if (SubResult.isInvalid()) return ExprError();
 
-      Expr *SubExpr = SubResult.take();
+      Expr *SubExpr = SubResult.get();
       E->setSubExpr(SubExpr);
       E->setType(SubExpr->getType());
       E->setValueKind(SubExpr->getValueKind());
@@ -12768,7 +12996,7 @@
       ExprResult SubResult = Visit(E->getSubExpr());
       if (SubResult.isInvalid()) return ExprError();
 
-      Expr *SubExpr = SubResult.take();
+      Expr *SubExpr = SubResult.get();
       E->setSubExpr(SubExpr);
       E->setType(S.Context.getPointerType(SubExpr->getType()));
       assert(E->getValueKind() == VK_RValue);
@@ -12805,7 +13033,7 @@
 static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *FunctionExpr) {
   ExprResult Result = RebuildUnknownAnyFunction(S).Visit(FunctionExpr);
   if (Result.isInvalid()) return ExprError();
-  return S.DefaultFunctionArrayConversion(Result.take());
+  return S.DefaultFunctionArrayConversion(Result.get());
 }
 
 namespace {
@@ -12842,7 +13070,7 @@
     template <class T> ExprResult rebuildSugarExpr(T *E) {
       ExprResult SubResult = Visit(E->getSubExpr());
       if (SubResult.isInvalid()) return ExprError();
-      Expr *SubExpr = SubResult.take();
+      Expr *SubExpr = SubResult.get();
       E->setSubExpr(SubExpr);
       E->setType(SubExpr->getType());
       E->setValueKind(SubExpr->getValueKind());
@@ -12873,7 +13101,7 @@
       DestType = Ptr->getPointeeType();
       ExprResult SubResult = Visit(E->getSubExpr());
       if (SubResult.isInvalid()) return ExprError();
-      E->setSubExpr(SubResult.take());
+      E->setSubExpr(SubResult.get());
       return E;
     }
 
@@ -12995,7 +13223,7 @@
   // Finally, we can recurse.
   ExprResult CalleeResult = Visit(CalleeExpr);
   if (!CalleeResult.isUsable()) return ExprError();
-  E->setCallee(CalleeResult.take());
+  E->setCallee(CalleeResult.get());
 
   // Bind a temporary if necessary.
   return S.MaybeBindToTemporary(E);
@@ -13036,8 +13264,8 @@
     ExprResult Result = Visit(E->getSubExpr());
     if (!Result.isUsable()) return ExprError();
   
-    E->setSubExpr(Result.take());
-    return S.Owned(E);
+    E->setSubExpr(Result.get());
+    return E;
   } else if (E->getCastKind() == CK_LValueToRValue) {
     assert(E->getValueKind() == VK_RValue);
     assert(E->getObjectKind() == OK_Ordinary);
@@ -13052,8 +13280,8 @@
     ExprResult Result = Visit(E->getSubExpr());
     if (!Result.isUsable()) return ExprError();
 
-    E->setSubExpr(Result.take());
-    return S.Owned(E);
+    E->setSubExpr(Result.get());
+    return E;
   } else {
     llvm_unreachable("Unhandled cast type!");
   }
@@ -13071,7 +13299,7 @@
       DestType = Ptr->getPointeeType();
       ExprResult Result = resolveDecl(E, VD);
       if (Result.isInvalid()) return ExprError();
-      return S.ImpCastExprToType(Result.take(), Type,
+      return S.ImpCastExprToType(Result.get(), Type,
                                  CK_FunctionToPointerDecay, VK_RValue);
     }
 
@@ -13113,7 +13341,7 @@
   VD->setType(DestType);
   E->setType(Type);
   E->setValueKind(ValueKind);
-  return S.Owned(E);
+  return E;
 }
 
 /// Check a cast of an unknown-any type.  We intentionally only
@@ -13125,7 +13353,7 @@
   ExprResult result = RebuildUnknownAnyExpr(*this, CastType).Visit(CastExpr);
   if (!result.isUsable()) return ExprError();
 
-  CastExpr = result.take();
+  CastExpr = result.get();
   VK = CastExpr->getValueKind();
   CastKind = CK_NoOp;
 
@@ -13156,7 +13384,7 @@
   InitializedEntity entity =
     InitializedEntity::InitializeParameter(Context, paramType,
                                            /*consumed*/ false);
-  return PerformCopyInitialization(entity, callLoc, Owned(arg));
+  return PerformCopyInitialization(entity, callLoc, arg);
 }
 
 static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {
@@ -13206,7 +13434,7 @@
 /// Returns true if there was an error and no recovery was possible.
 ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
   const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType();
-  if (!placeholderType) return Owned(E);
+  if (!placeholderType) return E;
 
   switch (placeholderType->getKind()) {
 
@@ -13214,7 +13442,7 @@
   case BuiltinType::Overload: {
     // Try to resolve a single function template specialization.
     // This is obligatory.
-    ExprResult result = Owned(E);
+    ExprResult result = E;
     if (ResolveAndFixSingleFunctionTemplateSpecialization(result, false)) {
       return result;
 
@@ -13228,7 +13456,7 @@
 
   // Bound member functions.
   case BuiltinType::BoundMember: {
-    ExprResult result = Owned(E);
+    ExprResult result = E;
     tryToRecoverWithCall(result, PDiag(diag::err_bound_member_function),
                          /*complain*/ true);
     return result;
@@ -13238,7 +13466,7 @@
   case BuiltinType::ARCUnbridgedCast: {
     Expr *realCast = stripARCUnbridgedCast(E);
     diagnoseARCUnbridgedCast(realCast);
-    return Owned(realCast);
+    return realCast;
   }
 
   // Expressions of unknown type.
@@ -13289,6 +13517,6 @@
   }
   if (Context.getBOOLDecl())
     BoolT = Context.getBOOLType();
-  return Owned(new (Context) ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes,
-                                        BoolT, OpLoc));
+  return new (Context)
+      ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc);
 }
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e84f2f3..fc3ede0 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -15,6 +15,7 @@
 #include "clang/Sema/SemaInternal.h"
 #include "TypeLocBuilder.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclObjC.h"
@@ -379,9 +380,8 @@
       RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
     return ExprError();
 
-  return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
-                                           Operand,
-                                           SourceRange(TypeidLoc, RParenLoc)));
+  return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand,
+                                     SourceRange(TypeidLoc, RParenLoc));
 }
 
 /// \brief Build a C++ typeid expression with an expression operand.
@@ -393,7 +393,7 @@
     if (E->getType()->isPlaceholderType()) {
       ExprResult result = CheckPlaceholderExpr(E);
       if (result.isInvalid()) return ExprError();
-      E = result.take();
+      E = result.get();
     }
 
     QualType T = E->getType();
@@ -414,7 +414,7 @@
         // and recheck the subexpression.
         ExprResult Result = TransformToPotentiallyEvaluated(E);
         if (Result.isInvalid()) return ExprError();
-        E = Result.take();
+        E = Result.get();
 
         // We require a vtable to query the type at run time.
         MarkVTableUsed(TypeidLoc, RecordD);
@@ -430,13 +430,12 @@
     QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
     if (!Context.hasSameType(T, UnqualT)) {
       T = UnqualT;
-      E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).take();
+      E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get();
     }
   }
 
-  return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
-                                           E,
-                                           SourceRange(TypeidLoc, RParenLoc)));
+  return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
+                                     SourceRange(TypeidLoc, RParenLoc));
 }
 
 /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
@@ -502,9 +501,8 @@
     }
   }
 
-  return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
-                                           Operand,
-                                           SourceRange(TypeidLoc, RParenLoc)));
+  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand,
+                                     SourceRange(TypeidLoc, RParenLoc));
 }
 
 /// \brief Build a Microsoft __uuidof expression with an expression operand.
@@ -523,9 +521,8 @@
     }
   }
 
-  return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
-                                           E,
-                                           SourceRange(TypeidLoc, RParenLoc)));
+  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E,
+                                     SourceRange(TypeidLoc, RParenLoc));
 }
 
 /// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
@@ -567,14 +564,14 @@
 Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
   assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
          "Unknown C++ Boolean value!");
-  return Owned(new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true,
-                                                Context.BoolTy, OpLoc));
+  return new (Context)
+      CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
 }
 
 /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
 ExprResult
 Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
-  return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
+  return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc);
 }
 
 /// ActOnCXXThrow - Parse throw expressions.
@@ -621,16 +618,19 @@
   if (!getLangOpts().CXXExceptions &&
       !getSourceManager().isInSystemHeader(OpLoc))
     Diag(OpLoc, diag::err_exceptions_disabled) << "throw";
-  
+
+  if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
+    Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
+
   if (Ex && !Ex->isTypeDependent()) {
     ExprResult ExRes = CheckCXXThrowOperand(OpLoc, Ex, IsThrownVarInScope);
     if (ExRes.isInvalid())
       return ExprError();
-    Ex = ExRes.take();
+    Ex = ExRes.get();
   }
   
-  return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc,
-                                          IsThrownVarInScope));
+  return new (Context)
+      CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
 }
 
 /// CheckCXXThrowOperand - Validate the operand of a throw.
@@ -644,12 +644,12 @@
   //   or "pointer to function returning T", [...]
   if (E->getType().hasQualifiers())
     E = ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
-                          E->getValueKind()).take();
+                          E->getValueKind()).get();
 
   ExprResult Res = DefaultFunctionArrayConversion(E);
   if (Res.isInvalid())
     return ExprError();
-  E = Res.take();
+  E = Res.get();
 
   //   If the type of the exception would be an incomplete type or a pointer
   //   to an incomplete type other than (cv) void the program is ill-formed.
@@ -697,12 +697,12 @@
                                         IsThrownVarInScope);
   if (Res.isInvalid())
     return ExprError();
-  E = Res.take();
+  E = Res.get();
 
   // If the exception has class type, we need additional handling.
   const RecordType *RecordTy = Ty->getAs<RecordType>();
   if (!RecordTy)
-    return Owned(E);
+    return E;
   CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
 
   // If we are throwing a polymorphic class type or pointer thereof,
@@ -711,22 +711,22 @@
 
   // If a pointer is thrown, the referenced object will not be destroyed.
   if (isPointer)
-    return Owned(E);
+    return E;
 
   // If the class has a destructor, we must be able to call it.
   if (RD->hasIrrelevantDestructor())
-    return Owned(E);
+    return E;
 
   CXXDestructorDecl *Destructor = LookupDestructor(RD);
   if (!Destructor)
-    return Owned(E);
+    return E;
 
   MarkFunctionReferenced(E->getExprLoc(), Destructor);
   CheckDestructorAccess(E->getExprLoc(), Destructor,
                         PDiag(diag::err_access_dtor_exception) << Ty);
   if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
     return ExprError();
-  return Owned(E);
+  return E;
 }
 
 QualType Sema::getCurrentThisType() {
@@ -736,7 +736,20 @@
     if (method && method->isInstance())
       ThisTy = method->getThisType(Context);
   }
-  
+  if (ThisTy.isNull()) {
+    if (isGenericLambdaCallOperatorSpecialization(CurContext) &&
+        CurContext->getParent()->getParent()->isRecord()) {
+      // This is a generic lambda call operator that is being instantiated
+      // within a default initializer - so use the enclosing class as 'this'.
+      // There is no enclosing member function to retrieve the 'this' pointer
+      // from.
+      QualType ClassTy = Context.getTypeDeclType(
+          cast<CXXRecordDecl>(CurContext->getParent()->getParent()));
+      // There are no cv-qualifiers for 'this' within default initializers, 
+      // per [expr.prim.general]p4.
+      return Context.getPointerType(ClassTy);
+    }
+  }
   return ThisTy;
 }
 
@@ -853,7 +866,7 @@
   if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use);
 
   CheckCXXThisCapture(Loc);
-  return Owned(new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false));
+  return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false);
 }
 
 bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
@@ -897,10 +910,8 @@
   SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
 
   if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
-    return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo,
-                                                    LParenLoc,
-                                                    Exprs,
-                                                    RParenLoc));
+    return CXXUnresolvedConstructExpr::Create(Context, TInfo, LParenLoc, Exprs,
+                                              RParenLoc);
   }
 
   bool ListInitialization = LParenLoc.isInvalid();
@@ -956,9 +967,9 @@
     // want, since it will be treated as an initializer list in further
     // processing. Explicitly insert a cast here.
     QualType ResultType = Result.get()->getType();
-    Result = Owned(CXXFunctionalCastExpr::Create(
+    Result = CXXFunctionalCastExpr::Create(
         Context, ResultType, Expr::getValueKindForType(TInfo->getType()), TInfo,
-        CK_NoOp, Result.take(), /*Path=*/ nullptr, LParenLoc, RParenLoc));
+        CK_NoOp, Result.get(), /*Path=*/nullptr, LParenLoc, RParenLoc);
   }
 
   // FIXME: Improve AST representation?
@@ -1082,12 +1093,12 @@
             Array.NumElts
              = CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value,
                                                 CCEK_NewExpr)
-                 .take();
+                 .get();
           } else {
             Array.NumElts
               = VerifyIntegerConstantExpression(NumElts, nullptr,
                                                 diag::err_new_array_nonconst)
-                  .take();
+                  .get();
           }
           if (!Array.NumElts)
             return ExprError();
@@ -1243,7 +1254,7 @@
   if (ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(ArraySize);
     if (result.isInvalid()) return ExprError();
-    ArraySize = result.take();
+    ArraySize = result.get();
   }
   // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have
   //   integral or enumeration type with a non-negative value."
@@ -1325,7 +1336,7 @@
     if (ConvertedSize.isInvalid())
       return ExprError();
 
-    ArraySize = ConvertedSize.take();
+    ArraySize = ConvertedSize.get();
     QualType SizeType = ArraySize->getType();
 
     if (!SizeType->isIntegralOrUnscopedEnumerationType())
@@ -1501,9 +1512,9 @@
     // we don't want the initialized object to be destructed.
     if (CXXBindTemporaryExpr *Binder =
             dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
-      FullInit = Owned(Binder->getSubExpr());
+      FullInit = Binder->getSubExpr();
 
-    Initializer = FullInit.take();
+    Initializer = FullInit.get();
   }
 
   // Mark the new and delete operators as referenced.
@@ -1536,13 +1547,11 @@
     }
   }
 
-  return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
-                                        OperatorDelete,
-                                        UsualArrayDeleteWantsSize,
-                                        PlacementArgs, TypeIdParens,
-                                        ArraySize, initStyle, Initializer,
-                                        ResultType, AllocTypeInfo,
-                                        Range, DirectInitRange));
+  return new (Context)
+      CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete,
+                 UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens,
+                 ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo,
+                 Range, DirectInitRange);
 }
 
 /// \brief Checks that a type is suitable as the allocated type
@@ -2241,14 +2250,14 @@
   //
   // DR599 amends "pointer type" to "pointer to object type" in both cases.
 
-  ExprResult Ex = Owned(ExE);
+  ExprResult Ex = ExE;
   FunctionDecl *OperatorDelete = nullptr;
   bool ArrayFormAsWritten = ArrayForm;
   bool UsualArrayDeleteWantsSize = false;
 
   if (!Ex.get()->isTypeDependent()) {
     // Perform lvalue-to-rvalue cast, if needed.
-    Ex = DefaultLvalueConversion(Ex.take());
+    Ex = DefaultLvalueConversion(Ex.get());
     if (Ex.isInvalid())
       return ExprError();
 
@@ -2307,7 +2316,7 @@
       }
     } Converter;
 
-    Ex = PerformContextualImplicitConversion(StartLoc, Ex.take(), Converter);
+    Ex = PerformContextualImplicitConversion(StartLoc, Ex.get(), Converter);
     if (Ex.isInvalid())
       return ExprError();
     Type = Ex.get()->getType();
@@ -2432,10 +2441,9 @@
     }
   }
 
-  return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
-                                           ArrayFormAsWritten,
-                                           UsualArrayDeleteWantsSize,
-                                           OperatorDelete, Ex.take(), StartLoc));
+  return new (Context) CXXDeleteExpr(
+      Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten,
+      UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc);
 }
 
 /// \brief Check the use of the given variable as a C++ condition in an if,
@@ -2459,19 +2467,15 @@
                           diag::err_invalid_use_of_array_type)
                      << ConditionVar->getSourceRange());
 
-  ExprResult Condition =
-    Owned(DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
-                              SourceLocation(),
-                              ConditionVar,
-                              /*enclosing*/ false,
-                              ConditionVar->getLocation(),
-                              ConditionVar->getType().getNonReferenceType(),
-                              VK_LValue));
+  ExprResult Condition = DeclRefExpr::Create(
+      Context, NestedNameSpecifierLoc(), SourceLocation(), ConditionVar,
+      /*enclosing*/ false, ConditionVar->getLocation(),
+      ConditionVar->getType().getNonReferenceType(), VK_LValue);
 
   MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get()));
 
   if (ConvertToBoolean) {
-    Condition = CheckBooleanCondition(Condition.take(), StmtLoc);
+    Condition = CheckBooleanCondition(Condition.get(), StmtLoc);
     if (Condition.isInvalid())
       return ExprError();
   }
@@ -2564,7 +2568,7 @@
     if (Result.isInvalid())
       return ExprError();
 
-    return S.MaybeBindToTemporary(Result.takeAs<Expr>());
+    return S.MaybeBindToTemporary(Result.getAs<Expr>());
   }
 
   case CK_UserDefinedConversion: {
@@ -2577,11 +2581,9 @@
     if (Result.isInvalid())
       return ExprError();
     // Record usage of conversion in an implicit cast.
-    Result = S.Owned(ImplicitCastExpr::Create(S.Context,
-                                              Result.get()->getType(),
-                                              CK_UserDefinedConversion,
-                                              Result.get(), nullptr,
-                                              Result.get()->getValueKind()));
+    Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(),
+                                      CK_UserDefinedConversion, Result.get(),
+                                      nullptr, Result.get()->getValueKind());
 
     S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
 
@@ -2606,7 +2608,7 @@
                                                Action, CCK);
     if (Res.isInvalid())
       return ExprError();
-    From = Res.take();
+    From = Res.get();
     break;
   }
 
@@ -2642,7 +2644,7 @@
                                     CCK);
         if (Res.isInvalid())
           return ExprError();
-        From = Res.take();
+        From = Res.get();
       }
 
       ExprResult CastArg
@@ -2657,7 +2659,7 @@
       if (CastArg.isInvalid())
         return ExprError();
 
-      From = CastArg.take();
+      From = CastArg.get();
 
       return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
                                        AA_Converting, CCK);
@@ -2677,7 +2679,7 @@
   }
 
   // Everything went well.
-  return Owned(From);
+  return From;
 }
 
 /// PerformImplicitConversion - Perform an implicit conversion of the
@@ -2757,20 +2759,20 @@
     FromType = FromType.getUnqualifiedType();
     ExprResult FromRes = DefaultLvalueConversion(From);
     assert(!FromRes.isInvalid() && "Can't perform deduced conversion?!");
-    From = FromRes.take();
+    From = FromRes.get();
     break;
   }
 
   case ICK_Array_To_Pointer:
     FromType = Context.getArrayDecayedType(FromType);
     From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay, 
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Function_To_Pointer:
     FromType = Context.getPointerType(FromType);
     From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay, 
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   default:
@@ -2794,7 +2796,7 @@
       return ExprError();
 
     From = ImpCastExprToType(From, ToType, CK_NoOp, 
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Integral_Promotion:
@@ -2804,17 +2806,17 @@
              SCS.Second == ICK_Integral_Promotion &&
              "only enums with fixed underlying type can promote to bool");
       From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean,
-                               VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     } else {
       From = ImpCastExprToType(From, ToType, CK_IntegralCast,
-                               VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     }
     break;
 
   case ICK_Floating_Promotion:
   case ICK_Floating_Conversion:
     From = ImpCastExprToType(From, ToType, CK_FloatingCast, 
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Complex_Promotion:
@@ -2833,22 +2835,22 @@
       CK = CK_IntegralComplexCast;
     }
     From = ImpCastExprToType(From, ToType, CK, 
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
   }
 
   case ICK_Floating_Integral:
     if (ToType->isRealFloatingType())
       From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, 
-                               VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     else
       From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral, 
-                               VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Compatible_Conversion:
       From = ImpCastExprToType(From, ToType, CK_NoOp, 
-                               VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Writeback_Conversion:
@@ -2893,12 +2895,12 @@
     if (Kind == CK_BlockPointerToObjCPointerCast) {
       ExprResult E = From;
       (void) PrepareCastToObjCObjectPointer(E);
-      From = E.take();
+      From = E.get();
     }
     if (getLangOpts().ObjCAutoRefCount)
       CheckObjCARCConversion(SourceRange(), ToType, From, CCK);
     From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
-             .take();
+             .get();
     break;
   }
 
@@ -2910,20 +2912,20 @@
     if (CheckExceptionSpecCompatibility(From, ToType))
       return ExprError();
     From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
-             .take();
+             .get();
     break;
   }
 
   case ICK_Boolean_Conversion:
     // Perform half-to-boolean conversion via float.
     if (From->getType()->isHalfType()) {
-      From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).take();
+      From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get();
       FromType = Context.FloatTy;
     }
 
     From = ImpCastExprToType(From, Context.BoolTy,
                              ScalarTypeToBooleanCastKind(FromType), 
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Derived_To_Base: {
@@ -2938,18 +2940,18 @@
 
     From = ImpCastExprToType(From, ToType.getNonReferenceType(),
                       CK_DerivedToBase, From->getValueKind(),
-                      &BasePath, CCK).take();
+                      &BasePath, CCK).get();
     break;
   }
 
   case ICK_Vector_Conversion:
     From = ImpCastExprToType(From, ToType, CK_BitCast, 
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Vector_Splat:
     From = ImpCastExprToType(From, ToType, CK_VectorSplat, 
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Complex_Real:
@@ -2963,16 +2965,16 @@
         // do nothing
       } else if (From->getType()->isRealFloatingType()) {
         From = ImpCastExprToType(From, ElType,
-                isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).take();
+                isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get();
       } else {
         assert(From->getType()->isIntegerType());
         From = ImpCastExprToType(From, ElType,
-                isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).take();
+                isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get();
       }
       // y -> _Complex y
       From = ImpCastExprToType(From, ToType,
                    isFloatingComplex ? CK_FloatingRealToComplex
-                                     : CK_IntegralRealToComplex).take();
+                                     : CK_IntegralRealToComplex).get();
 
     // Case 2.  _Complex x -> y
     } else {
@@ -2986,7 +2988,7 @@
       From = ImpCastExprToType(From, ElType,
                    isFloatingComplex ? CK_FloatingComplexToReal
                                      : CK_IntegralComplexToReal, 
-                               VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
 
       // x -> y
       if (Context.hasSameUnqualifiedType(ElType, ToType)) {
@@ -2994,29 +2996,29 @@
       } else if (ToType->isRealFloatingType()) {
         From = ImpCastExprToType(From, ToType,
                    isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating, 
-                                 VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                                 VK_RValue, /*BasePath=*/nullptr, CCK).get();
       } else {
         assert(ToType->isIntegerType());
         From = ImpCastExprToType(From, ToType,
                    isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast, 
-                                 VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                                 VK_RValue, /*BasePath=*/nullptr, CCK).get();
       }
     }
     break;
   
   case ICK_Block_Pointer_Conversion: {
     From = ImpCastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast,
-                             VK_RValue, /*BasePath=*/nullptr, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
   }
       
   case ICK_TransparentUnionConversion: {
-    ExprResult FromRes = Owned(From);
+    ExprResult FromRes = From;
     Sema::AssignConvertType ConvTy =
       CheckTransparentUnionArgumentConstraints(ToType, FromRes);
     if (FromRes.isInvalid())
       return ExprError();
-    From = FromRes.take();
+    From = FromRes.get();
     assert ((ConvTy == Sema::Compatible) &&
             "Improper transparent union conversion");
     (void)ConvTy;
@@ -3026,7 +3028,7 @@
   case ICK_Zero_Event_Conversion:
     From = ImpCastExprToType(From, ToType,
                              CK_ZeroToOCLEvent,
-                             From->getValueKind()).take();
+                             From->getValueKind()).get();
     break;
 
   case ICK_Lvalue_To_Rvalue:
@@ -3048,7 +3050,7 @@
     ExprValueKind VK = ToType->isReferenceType() ?
                                   From->getValueKind() : VK_RValue;
     From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
-                             CK_NoOp, VK, /*BasePath=*/nullptr, CCK).take();
+                             CK_NoOp, VK, /*BasePath=*/nullptr, CCK).get();
 
     if (SCS.DeprecatedStringLiteralToCharPtr &&
         !getLangOpts().WritableStrings) {
@@ -3071,10 +3073,10 @@
     assert(Context.hasSameType(
         ToAtomicType->castAs<AtomicType>()->getValueType(), From->getType()));
     From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic,
-                             VK_RValue, nullptr, CCK).take();
+                             VK_RValue, nullptr, CCK).get();
   }
 
-  return Owned(From);
+  return From;
 }
 
 /// \brief Check the completeness of a type in a unary type trait.
@@ -4002,9 +4004,8 @@
   // returns 'size_t'. On Windows, the primary platform for the Embarcadero
   // compiler, there is no difference. On several other platforms this is an
   // important distinction.
-  return Owned(new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value,
-                                                DimExpr, RParen,
-                                                Context.getSizeType()));
+  return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
+                                          RParen, Context.getSizeType());
 }
 
 ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
@@ -4037,13 +4038,13 @@
   } else if (Queried->getType()->isPlaceholderType()) {
     ExprResult PE = CheckPlaceholderExpr(Queried);
     if (PE.isInvalid()) return ExprError();
-    return BuildExpressionTrait(ET, KWLoc, PE.take(), RParen);
+    return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
   }
 
   bool Value = EvaluateExpressionTrait(ET, Queried);
 
-  return Owned(new (Context) ExpressionTraitExpr(KWLoc, ET, Queried, Value,
-                                                 RParen, Context.BoolTy));
+  return new (Context)
+      ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
 }
 
 QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
@@ -4056,12 +4057,12 @@
 
   // The LHS undergoes lvalue conversions if this is ->*.
   if (isIndirect) {
-    LHS = DefaultLvalueConversion(LHS.take());
+    LHS = DefaultLvalueConversion(LHS.get());
     if (LHS.isInvalid()) return QualType();
   }
 
   // The RHS always undergoes lvalue conversions.
-  RHS = DefaultLvalueConversion(RHS.take());
+  RHS = DefaultLvalueConversion(RHS.get());
   if (RHS.isInvalid()) return QualType();
 
   const char *OpSpelling = isIndirect ? "->*" : ".*";
@@ -4124,7 +4125,7 @@
     // Cast LHS to type of use.
     QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
     ExprValueKind VK = isIndirect ? VK_RValue : LHS.get()->getValueKind();
-    LHS = ImpCastExprToType(LHS.take(), UseType, CK_DerivedToBase, VK,
+    LHS = ImpCastExprToType(LHS.get(), UseType, CK_DerivedToBase, VK,
                             &BasePath);
   }
 
@@ -4347,7 +4348,7 @@
   InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
   InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getLocStart(),
                                                            SourceLocation());
-  Expr *Arg = E.take();
+  Expr *Arg = E.get();
   InitializationSequence InitSeq(Self, Entity, Kind, Arg);
   ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg);
   if (Result.isInvalid())
@@ -4371,7 +4372,7 @@
   // C++11 [expr.cond]p1
   //   The first expression is contextually converted to bool.
   if (!Cond.get()->isTypeDependent()) {
-    ExprResult CondRes = CheckCXXBooleanCondition(Cond.take());
+    ExprResult CondRes = CheckCXXBooleanCondition(Cond.get());
     if (CondRes.isInvalid())
       return QualType();
     Cond = CondRes;
@@ -4471,11 +4472,11 @@
     Qualifiers LCVR = Qualifiers::fromCVRMask(LTy.getCVRQualifiers());
     Qualifiers RCVR = Qualifiers::fromCVRMask(RTy.getCVRQualifiers());
     if (RCVR.isStrictSupersetOf(LCVR)) {
-      LHS = ImpCastExprToType(LHS.take(), RTy, CK_NoOp, LVK);
+      LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK);
       LTy = LHS.get()->getType();
     }
     else if (LCVR.isStrictSupersetOf(RCVR)) {
-      RHS = ImpCastExprToType(RHS.take(), LTy, CK_NoOp, RVK);
+      RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK);
       RTy = RHS.get()->getType();
     }
   }
@@ -4512,8 +4513,8 @@
   // C++11 [expr.cond]p6
   //   Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard
   //   conversions are performed on the second and third operands.
-  LHS = DefaultFunctionArrayLvalueConversion(LHS.take());
-  RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+  LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
+  RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
   if (LHS.isInvalid() || RHS.isInvalid())
     return QualType();
   LTy = LHS.get()->getType();
@@ -4640,12 +4641,12 @@
       !T2->isAnyPointerType() && !T2->isMemberPointerType()) {
     if (T1->isNullPtrType() &&
         E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
-      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take();
+      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get();
       return T1;
     }
     if (T2->isNullPtrType() &&
         E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
-      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take();
+      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get();
       return T2;
     }
     return QualType();
@@ -4653,16 +4654,16 @@
 
   if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T2->isMemberPointerType())
-      E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).take();
+      E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).get();
     else
-      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take();
+      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get();
     return T2;
   }
   if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T1->isMemberPointerType())
-      E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).take();
+      E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).get();
     else
-      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take();
+      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get();
     return T1;
   }
 
@@ -4800,14 +4801,14 @@
       = E1ToC1.Perform(*this, Entity1, Kind, E1);
     if (E1Result.isInvalid())
       return QualType();
-    E1 = E1Result.takeAs<Expr>();
+    E1 = E1Result.getAs<Expr>();
 
     // Convert E2 to Composite1
     ExprResult E2Result
       = E2ToC1.Perform(*this, Entity1, Kind, E2);
     if (E2Result.isInvalid())
       return QualType();
-    E2 = E2Result.takeAs<Expr>();
+    E2 = E2Result.getAs<Expr>();
 
     return Composite1;
   }
@@ -4825,14 +4826,14 @@
     = E1ToC2.Perform(*this, Entity2, Kind, E1);
   if (E1Result.isInvalid())
     return QualType();
-  E1 = E1Result.takeAs<Expr>();
+  E1 = E1Result.getAs<Expr>();
 
   // Convert E2 to Composite2
   ExprResult E2Result
     = E2ToC2.Perform(*this, Entity2, Kind, E2);
   if (E2Result.isInvalid())
     return QualType();
-  E2 = E2Result.takeAs<Expr>();
+  E2 = E2Result.getAs<Expr>();
 
   return Composite2;
 }
@@ -4845,7 +4846,7 @@
 
   // If the result is a glvalue, we shouldn't bind it.
   if (!E->isRValue())
-    return Owned(E);
+    return E;
 
   // In ARC, calls that return a retainable type can return retained,
   // in which case we have to insert a consuming cast.
@@ -4888,7 +4889,7 @@
     // we don't want any extra casts here.
     } else if (isa<CastExpr>(E) &&
                isa<BlockExpr>(cast<CastExpr>(E)->getSubExpr())) {
-      return Owned(E);
+      return E;
 
     // For message sends and property references, we try to find an
     // actual method.  FIXME: we should infer retention by selector in
@@ -4913,23 +4914,23 @@
       // return an object.
       if (!ReturnsRetained &&
           D && D->getMethodFamily() == OMF_performSelector)
-        return Owned(E);
+        return E;
     }
 
     // Don't reclaim an object of Class type.
     if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
-      return Owned(E);
+      return E;
 
     ExprNeedsCleanups = true;
 
     CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
                                    : CK_ARCReclaimReturnedObject);
-    return Owned(ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
-                                          VK_RValue));
+    return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
+                                    VK_RValue);
   }
 
   if (!getLangOpts().CPlusPlus)
-    return Owned(E);
+    return E;
 
   // Search for the base element type (cf. ASTContext::getBaseElementType) with
   // a fast path for the common case that the type is directly a RecordType.
@@ -4947,7 +4948,7 @@
       T = cast<ArrayType>(T)->getElementType().getTypePtr();
       break;
     default:
-      return Owned(E);
+      return E;
     }
   }
 
@@ -4955,7 +4956,7 @@
   // not processing a decltype expression.
   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
   if (RD->isInvalidDecl() || RD->isDependentContext())
-    return Owned(E);
+    return E;
 
   bool IsDecltype = ExprEvalContexts.back().IsDecltype;
   CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD);
@@ -4970,7 +4971,7 @@
 
     // If destructor is trivial, we can avoid the extra copy.
     if (Destructor->isTrivial())
-      return Owned(E);
+      return E;
 
     // We need a cleanup, but we don't need to remember the temporary.
     ExprNeedsCleanups = true;
@@ -4982,7 +4983,7 @@
   if (IsDecltype)
     ExprEvalContexts.back().DelayedDecltypeBinds.push_back(Bind);
 
-  return Owned(Bind);
+  return Bind;
 }
 
 ExprResult
@@ -4990,7 +4991,7 @@
   if (SubExpr.isInvalid())
     return ExprError();
 
-  return Owned(MaybeCreateExprWithCleanups(SubExpr.take()));
+  return MaybeCreateExprWithCleanups(SubExpr.get());
 }
 
 Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {
@@ -5056,8 +5057,8 @@
     if (SubExpr.isInvalid())
       return ExprError();
     if (SubExpr.get() == PE->getSubExpr())
-      return Owned(E);
-    return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.take());
+      return E;
+    return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get());
   }
   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
     if (BO->getOpcode() == BO_Comma) {
@@ -5065,13 +5066,10 @@
       if (RHS.isInvalid())
         return ExprError();
       if (RHS.get() == BO->getRHS())
-        return Owned(E);
-      return Owned(new (Context) BinaryOperator(BO->getLHS(), RHS.take(),
-                                                BO_Comma, BO->getType(),
-                                                BO->getValueKind(),
-                                                BO->getObjectKind(),
-                                                BO->getOperatorLoc(),
-                                                BO->isFPContractable()));
+        return E;
+      return new (Context) BinaryOperator(
+          BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(),
+          BO->getObjectKind(), BO->getOperatorLoc(), BO->isFPContractable());
     }
   }
 
@@ -5089,7 +5087,7 @@
   // In MS mode, don't perform any extra checking of call return types within a
   // decltype expression.
   if (getLangOpts().MSVCCompat)
-    return Owned(E);
+    return E;
 
   // Perform the semantic checks we delayed until this point.
   for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size();
@@ -5132,12 +5130,12 @@
   }
 
   // Possibly strip off the top CXXBindTemporaryExpr.
-  return Owned(E);
+  return E;
 }
 
 /// Note a set of 'operator->' functions that were used for a member access.
 static void noteOperatorArrows(Sema &S,
-                               llvm::ArrayRef<FunctionDecl *> OperatorArrows) {
+                               ArrayRef<FunctionDecl *> OperatorArrows) {
   unsigned SkipStart = OperatorArrows.size(), SkipCount = 0;
   // FIXME: Make this configurable?
   unsigned Limit = 9;
@@ -5172,7 +5170,7 @@
 
   Result = CheckPlaceholderExpr(Base);
   if (Result.isInvalid()) return ExprError();
-  Base = Result.take();
+  Base = Result.get();
 
   QualType BaseType = Base->getType();
   MayBePseudoDestructor = false;
@@ -5186,7 +5184,7 @@
 
     ObjectType = ParsedType::make(BaseType);
     MayBePseudoDestructor = true;
-    return Owned(Base);
+    return Base;
   }
 
   // C++ [over.match.oper]p8:
@@ -5276,7 +5274,7 @@
   } else if (!BaseType->isRecordType()) {
     ObjectType = ParsedType();
     MayBePseudoDestructor = true;
-    return Owned(Base);
+    return Base;
   }
 
   // The object type must be complete (or dependent), or
@@ -5317,7 +5315,7 @@
   if (Base->hasPlaceholderType()) {
     ExprResult result = S.CheckPlaceholderExpr(Base);
     if (result.isInvalid()) return true;
-    Base = result.take();
+    Base = result.get();
   }
   ObjectType = Base->getType();
 
@@ -5442,7 +5440,7 @@
                                             Destructed);
 
   if (HasTrailingLParen)
-    return Owned(Result);
+    return Result;
 
   return DiagnoseDtorReference(Destructed.getLocation(), Result);
 }
@@ -5644,7 +5642,7 @@
     return true;
 
   MemberExpr *ME =
-      new (Context) MemberExpr(Exp.take(), /*IsArrow=*/false, Method,
+      new (Context) MemberExpr(Exp.get(), /*IsArrow=*/false, Method,
                                SourceLocation(), Context.BoundMemberTy,
                                VK_RValue, OK_Ordinary);
   if (HadMultipleCandidates)
@@ -5664,8 +5662,8 @@
 ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
                                       SourceLocation RParen) {
   CanThrowResult CanThrow = canThrow(Operand);
-  return Owned(new (Context) CXXNoexceptExpr(Context.BoolTy, Operand,
-                                             CanThrow, KeyLoc, RParen));
+  return new (Context)
+      CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen);
 }
 
 ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
@@ -5733,8 +5731,8 @@
 ExprResult Sema::IgnoredValueConversions(Expr *E) {
   if (E->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
-    if (result.isInvalid()) return Owned(E);
-    E = result.take();
+    if (result.isInvalid()) return E;
+    E = result.get();
   }
 
   // C99 6.3.2.1:
@@ -5749,7 +5747,7 @@
     if (!getLangOpts().CPlusPlus && E->getType()->isFunctionType())
       return DefaultFunctionArrayConversion(E);
 
-    return Owned(E);
+    return E;
   }
 
   if (getLangOpts().CPlusPlus)  {
@@ -5762,30 +5760,30 @@
         IsSpecialDiscardedValue(E)) {
       ExprResult Res = DefaultLvalueConversion(E);
       if (Res.isInvalid())
-        return Owned(E);
-      E = Res.take();
+        return E;
+      E = Res.get();
     } 
-    return Owned(E);
+    return E;
   }
 
   // GCC seems to also exclude expressions of incomplete enum type.
   if (const EnumType *T = E->getType()->getAs<EnumType>()) {
     if (!T->getDecl()->isComplete()) {
       // FIXME: stupid workaround for a codegen bug!
-      E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).take();
-      return Owned(E);
+      E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get();
+      return E;
     }
   }
 
   ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
   if (Res.isInvalid())
-    return Owned(E);
-  E = Res.take();
+    return E;
+  E = Res.get();
 
   if (!E->getType()->isVoidType())
     RequireCompleteType(E->getExprLoc(), E->getType(),
                         diag::err_incomplete_type);
-  return Owned(E);
+  return E;
 }
 
 // If we can unambiguously determine whether Var can never be used
@@ -5924,7 +5922,7 @@
                                      bool DiscardedValue,
                                      bool IsConstexpr, 
                                      bool IsLambdaInitCaptureInitializer) {
-  ExprResult FullExpr = Owned(FE);
+  ExprResult FullExpr = FE;
 
   if (!FullExpr.get())
     return ExprError();
@@ -5951,17 +5949,17 @@
   // Top-level expressions default to 'id' when we're in a debugger.
   if (DiscardedValue && getLangOpts().DebuggerCastResultToId &&
       FullExpr.get()->getType() == Context.UnknownAnyTy) {
-    FullExpr = forceUnknownAnyToType(FullExpr.take(), Context.getObjCIdType());
+    FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType());
     if (FullExpr.isInvalid())
       return ExprError();
   }
 
   if (DiscardedValue) {
-    FullExpr = CheckPlaceholderExpr(FullExpr.take());
+    FullExpr = CheckPlaceholderExpr(FullExpr.get());
     if (FullExpr.isInvalid())
       return ExprError();
 
-    FullExpr = IgnoredValueConversions(FullExpr.take());
+    FullExpr = IgnoredValueConversions(FullExpr.get());
     if (FullExpr.isInvalid())
       return ExprError();
   }
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 5e9ccff..b73ebc4 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -472,12 +472,10 @@
 
   // Get the type being accessed in BaseType.  If this is an arrow, the BaseExpr
   // must have pointer type, and the accessed type is the pointee.
-  return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType,
-                                                   IsArrow, OpLoc,
-                                               SS.getWithLocInContext(Context),
-                                                   TemplateKWLoc,
-                                                   FirstQualifierInScope,
-                                                   NameInfo, TemplateArgs));
+  return CXXDependentScopeMemberExpr::Create(
+      Context, BaseExpr, BaseType, IsArrow, OpLoc,
+      SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope,
+      NameInfo, TemplateArgs);
 }
 
 /// We know that the given qualified member reference points only to
@@ -672,6 +670,11 @@
   return false;
 }
 
+static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
+                                   ExprResult &BaseExpr, bool &IsArrow,
+                                   SourceLocation OpLoc, CXXScopeSpec &SS,
+                                   Decl *ObjCImpDecl, bool HasTemplateArgs);
+
 ExprResult
 Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
                                SourceLocation OpLoc, bool IsArrow,
@@ -679,7 +682,8 @@
                                SourceLocation TemplateKWLoc,
                                NamedDecl *FirstQualifierInScope,
                                const DeclarationNameInfo &NameInfo,
-                               const TemplateArgumentListInfo *TemplateArgs) {
+                               const TemplateArgumentListInfo *TemplateArgs,
+                               ActOnMemberAccessExtraArgs *ExtraArgs) {
   if (BaseType->isDependentType() ||
       (SS.isSet() && isDependentScopeSpecifier(SS)))
     return ActOnDependentMemberExpr(Base, BaseType,
@@ -700,19 +704,18 @@
 
   // Explicit member accesses.
   } else {
-    ExprResult BaseResult = Owned(Base);
-    ExprResult Result =
-      LookupMemberExpr(R, BaseResult, IsArrow, OpLoc,
-                       SS, /*ObjCImpDecl*/ nullptr, TemplateArgs != nullptr);
+    ExprResult BaseResult = Base;
+    ExprResult Result = LookupMemberExpr(
+        *this, R, BaseResult, IsArrow, OpLoc, SS,
+        ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr,
+        TemplateArgs != nullptr);
 
     if (BaseResult.isInvalid())
       return ExprError();
-    Base = BaseResult.take();
+    Base = BaseResult.get();
 
-    if (Result.isInvalid()) {
-      Owned(Base);
+    if (Result.isInvalid())
       return ExprError();
-    }
 
     if (Result.get())
       return Result;
@@ -723,7 +726,8 @@
 
   return BuildMemberReferenceExpr(Base, BaseType,
                                   OpLoc, IsArrow, SS, TemplateKWLoc,
-                                  FirstQualifierInScope, R, TemplateArgs);
+                                  FirstQualifierInScope, R, TemplateArgs,
+                                  false, ExtraArgs);
 }
 
 static ExprResult
@@ -763,7 +767,7 @@
       = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
     if (result.isInvalid()) return ExprError();
     
-    baseObjectExpr = result.take();    
+    baseObjectExpr = result.get();    
     baseObjectIsPointer = false;
     baseQuals = baseObjectExpr->getType().getQualifiers();
     
@@ -819,7 +823,7 @@
     
     result = BuildFieldReferenceExpr(*this, result, baseObjectIsPointer,
                                      EmptySS, field, foundDecl,
-                                     memberNameInfo).take();
+                                     memberNameInfo).get();
     if (!result)
       return ExprError();
 
@@ -839,10 +843,10 @@
 
     result = BuildFieldReferenceExpr(*this, result, /*isarrow*/ false,
                                      (FI == FEnd? SS : EmptySS), field,
-                                     fakeFoundDecl, memberNameInfo).take();
+                                     fakeFoundDecl, memberNameInfo).get();
   }
   
-  return Owned(result);
+  return result;
 }
 
 static ExprResult
@@ -1013,7 +1017,7 @@
                                      TemplateKWLoc, MemberNameInfo,
                                      TemplateArgs, R.begin(), R.end());
 
-    return Owned(MemExpr);
+    return MemExpr;
   }
 
   assert(R.isSingleResult());
@@ -1050,10 +1054,8 @@
   }
 
   // Check the use of this member.
-  if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc)) {
-    Owned(BaseExpr);
+  if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc))
     return ExprError();
-  }
 
   if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
     return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow,
@@ -1071,10 +1073,10 @@
                                                     OpLoc);
 
   if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
-    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
-                                 TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
-                                 Var->getType().getNonReferenceType(),
-                                 VK_LValue, OK_Ordinary));
+    return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+                           Var, FoundDecl, MemberNameInfo,
+                           Var->getType().getNonReferenceType(), VK_LValue,
+                           OK_Ordinary);
   }
 
   if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
@@ -1088,21 +1090,18 @@
       type = MemberFn->getType();
     }
 
-    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, 
-                                 TemplateKWLoc, MemberFn, FoundDecl, 
-                                 MemberNameInfo, type, valueKind,
-                                 OK_Ordinary));
+    return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+                           MemberFn, FoundDecl, MemberNameInfo, type, valueKind,
+                           OK_Ordinary);
   }
   assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");
 
   if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
-    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
-                                 TemplateKWLoc, Enum, FoundDecl, MemberNameInfo,
-                                 Enum->getType(), VK_RValue, OK_Ordinary));
+    return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+                           Enum, FoundDecl, MemberNameInfo, Enum->getType(),
+                           VK_RValue, OK_Ordinary);
   }
 
-  Owned(BaseExpr);
-
   // We found something that we didn't expect. Complain.
   if (isa<TypeDecl>(MemberDecl))
     Diag(MemberLoc, diag::err_typecheck_member_reference_type)
@@ -1145,7 +1144,7 @@
   if (opty && !opty->getObjectType()->getInterface())
     return false;
 
-  base = S.ImpCastExprToType(base.take(), redef, CK_BitCast);
+  base = S.ImpCastExprToType(base.get(), redef, CK_BitCast);
   return true;
 }
 
@@ -1177,15 +1176,14 @@
 ///
 /// The ObjCImpDecl bit is a gross hack that will need to be properly
 /// fixed for ObjC++.
-ExprResult
-Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
-                       bool &IsArrow, SourceLocation OpLoc,
-                       CXXScopeSpec &SS,
-                       Decl *ObjCImpDecl, bool HasTemplateArgs) {
+static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
+                                   ExprResult &BaseExpr, bool &IsArrow,
+                                   SourceLocation OpLoc, CXXScopeSpec &SS,
+                                   Decl *ObjCImpDecl, bool HasTemplateArgs) {
   assert(BaseExpr.get() && "no base expression");
 
   // Perform default conversions.
-  BaseExpr = PerformMemberExprBaseConversion(BaseExpr.take(), IsArrow);
+  BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
   if (BaseExpr.isInvalid())
     return ExprError();
 
@@ -1213,8 +1211,8 @@
       // overloaded operator->, but that should have been dealt with
       // by now--or a diagnostic message already issued if a problem
       // was encountered while looking for the overloaded operator->.
-      if (!getLangOpts().CPlusPlus) {
-        Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+      if (!S.getLangOpts().CPlusPlus) {
+        S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
           << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
           << FixItHint::CreateReplacement(OpLoc, ".");
       }
@@ -1222,7 +1220,7 @@
     } else if (BaseType->isFunctionType()) {
       goto fail;
     } else {
-      Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
+      S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
         << BaseType << BaseExpr.get()->getSourceRange();
       return ExprError();
     }
@@ -1230,24 +1228,24 @@
 
   // Handle field access to simple records.
   if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
-    if (LookupMemberExprInRecord(*this, R, BaseExpr.get()->getSourceRange(),
+    if (LookupMemberExprInRecord(S, R, BaseExpr.get()->getSourceRange(),
                                  RTy, OpLoc, SS, HasTemplateArgs))
       return ExprError();
 
     // Returning valid-but-null is how we indicate to the caller that
     // the lookup result was filled in.
-    return Owned((Expr*) nullptr);
+    return ExprResult((Expr *)nullptr);
   }
 
   // Handle ivar access to Objective-C objects.
   if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
     if (!SS.isEmpty() && !SS.isInvalid()) {
-      Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
+      S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
         << 1 << SS.getScopeRep()
         << FixItHint::CreateRemoval(SS.getRange());
       SS.clear();
     }
-    
+
     IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
 
     // There are three cases for the base type:
@@ -1256,24 +1254,24 @@
     //   - an interface
     ObjCInterfaceDecl *IDecl = OTy->getInterface();
     if (!IDecl) {
-      if (getLangOpts().ObjCAutoRefCount &&
+      if (S.getLangOpts().ObjCAutoRefCount &&
           (OTy->isObjCId() || OTy->isObjCClass()))
         goto fail;
       // There's an implicit 'isa' ivar on all objects.
       // But we only actually find it this way on objects of type 'id',
       // apparently.
       if (OTy->isObjCId() && Member->isStr("isa"))
-        return Owned(new (Context) ObjCIsaExpr(BaseExpr.take(), IsArrow, MemberLoc,
-                                               OpLoc,
-                                               Context.getObjCClassType()));
-      if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
-        return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+        return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
+                                           OpLoc, S.Context.getObjCClassType());
+      if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                                 ObjCImpDecl, HasTemplateArgs);
       goto fail;
     }
-    
-    if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag,
-                            BaseExpr.get()))
+
+    if (S.RequireCompleteType(OpLoc, BaseType,
+                              diag::err_typecheck_incomplete_tag,
+                              BaseExpr.get()))
       return ExprError();
 
     ObjCInterfaceDecl *ClassDeclared = nullptr;
@@ -1283,14 +1281,14 @@
       // Attempt to correct for typos in ivar names.
       DeclFilterCCC<ObjCIvarDecl> Validator;
       Validator.IsObjCIvarLookup = IsArrow;
-      if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
-                                                 LookupMemberName, nullptr,
-                                                 nullptr, Validator,
-                                                 CTK_ErrorRecovery, IDecl)) {
+      if (TypoCorrection Corrected = S.CorrectTypo(
+              R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
+              Validator, Sema::CTK_ErrorRecovery, IDecl)) {
         IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
-        diagnoseTypo(Corrected,
-                     PDiag(diag::err_typecheck_member_reference_ivar_suggest)
-                          << IDecl->getDeclName() << MemberName);
+        S.diagnoseTypo(
+            Corrected,
+            S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
+                << IDecl->getDeclName() << MemberName);
 
         // Figure out the class that declares the ivar.
         assert(!ClassDeclared);
@@ -1300,20 +1298,19 @@
         ClassDeclared = cast<ObjCInterfaceDecl>(D);
       } else {
         if (IsArrow && IDecl->FindPropertyDeclaration(Member)) {
-          Diag(MemberLoc, 
-          diag::err_property_found_suggest)
-          << Member << BaseExpr.get()->getType()
-          << FixItHint::CreateReplacement(OpLoc, ".");
+          S.Diag(MemberLoc, diag::err_property_found_suggest)
+              << Member << BaseExpr.get()->getType()
+              << FixItHint::CreateReplacement(OpLoc, ".");
           return ExprError();
         }
 
-        Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
-          << IDecl->getDeclName() << MemberName
-          << BaseExpr.get()->getSourceRange();
+        S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
+            << IDecl->getDeclName() << MemberName
+            << BaseExpr.get()->getSourceRange();
         return ExprError();
       }
     }
-    
+
     assert(ClassDeclared);
 
     // If the decl being referenced had an error, return an error for this
@@ -1323,14 +1320,14 @@
       return ExprError();
 
     // Check whether we can reference this field.
-    if (DiagnoseUseOfDecl(IV, MemberLoc))
+    if (S.DiagnoseUseOfDecl(IV, MemberLoc))
       return ExprError();
     if (IV->getAccessControl() != ObjCIvarDecl::Public &&
         IV->getAccessControl() != ObjCIvarDecl::Package) {
       ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
-      if (ObjCMethodDecl *MD = getCurMethodDecl())
+      if (ObjCMethodDecl *MD = S.getCurMethodDecl())
         ClassOfMethodDecl =  MD->getClassInterface();
-      else if (ObjCImpDecl && getCurFunctionDecl()) {
+      else if (ObjCImpDecl && S.getCurFunctionDecl()) {
         // Case of a c-function declared inside an objc implementation.
         // FIXME: For a c-style function nested inside an objc implementation
         // class, there is no implementation context available, so we pass
@@ -1344,20 +1341,20 @@
                    dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
           ClassOfMethodDecl = CatImplClass->getClassInterface();
       }
-      if (!getLangOpts().DebuggerSupport) {
+      if (!S.getLangOpts().DebuggerSupport) {
         if (IV->getAccessControl() == ObjCIvarDecl::Private) {
           if (!declaresSameEntity(ClassDeclared, IDecl) ||
               !declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
-            Diag(MemberLoc, diag::error_private_ivar_access)
+            S.Diag(MemberLoc, diag::error_private_ivar_access)
               << IV->getDeclName();
         } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
           // @protected
-          Diag(MemberLoc, diag::error_protected_ivar_access)
-            << IV->getDeclName();
+          S.Diag(MemberLoc, diag::error_protected_ivar_access)
+              << IV->getDeclName();
       }
     }
     bool warn = true;
-    if (getLangOpts().ObjCAutoRefCount) {
+    if (S.getLangOpts().ObjCAutoRefCount) {
       Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
       if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
         if (UO->getOpcode() == UO_Deref)
@@ -1365,55 +1362,50 @@
       
       if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
         if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
-          Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
+          S.Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
           warn = false;
         }
     }
     if (warn) {
-      if (ObjCMethodDecl *MD = getCurMethodDecl()) {
+      if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
         ObjCMethodFamily MF = MD->getMethodFamily();
         warn = (MF != OMF_init && MF != OMF_dealloc && 
                 MF != OMF_finalize &&
-                !IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
+                !S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
       }
       if (warn)
-        Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
+        S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
     }
 
-    ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
-                                                            MemberLoc, OpLoc,
-                                                            BaseExpr.take(),
-                                                            IsArrow);
+    ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
+        IV, IV->getType(), MemberLoc, OpLoc, BaseExpr.get(), IsArrow);
 
-    if (getLangOpts().ObjCAutoRefCount) {
+    if (S.getLangOpts().ObjCAutoRefCount) {
       if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
-        DiagnosticsEngine::Level Level =
-          Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                   MemberLoc);
-        if (Level != DiagnosticsEngine::Ignored)
-          recordUseOfEvaluatedWeak(Result);
+        if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
+          S.recordUseOfEvaluatedWeak(Result);
       }
     }
 
-    return Owned(Result);
+    return Result;
   }
 
   // Objective-C property access.
   const ObjCObjectPointerType *OPT;
   if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
     if (!SS.isEmpty() && !SS.isInvalid()) {
-      Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
-        << 0 << SS.getScopeRep()
-        << FixItHint::CreateRemoval(SS.getRange());
+      S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
+          << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
       SS.clear();
     }
 
     // This actually uses the base as an r-value.
-    BaseExpr = DefaultLvalueConversion(BaseExpr.take());
+    BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
     if (BaseExpr.isInvalid())
       return ExprError();
 
-    assert(Context.hasSameUnqualifiedType(BaseType, BaseExpr.get()->getType()));
+    assert(S.Context.hasSameUnqualifiedType(BaseType,
+                                            BaseExpr.get()->getType()));
 
     IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
 
@@ -1422,78 +1414,75 @@
     // id, with and without qualifiers.
     if (OT->isObjCId()) {
       // Check protocols on qualified interfaces.
-      Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
-      if (Decl *PMDecl = FindGetterSetterNameDecl(OPT, Member, Sel, Context)) {
+      Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
+      if (Decl *PMDecl =
+              FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
         if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
           // Check the use of this declaration
-          if (DiagnoseUseOfDecl(PD, MemberLoc))
+          if (S.DiagnoseUseOfDecl(PD, MemberLoc))
             return ExprError();
 
-          return Owned(new (Context) ObjCPropertyRefExpr(PD,
-                                                         Context.PseudoObjectTy,
-                                                         VK_LValue,
-                                                         OK_ObjCProperty,
-                                                         MemberLoc, 
-                                                         BaseExpr.take()));
+          return new (S.Context)
+              ObjCPropertyRefExpr(PD, S.Context.PseudoObjectTy, VK_LValue,
+                                  OK_ObjCProperty, MemberLoc, BaseExpr.get());
         }
 
         if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
           // Check the use of this method.
-          if (DiagnoseUseOfDecl(OMD, MemberLoc))
+          if (S.DiagnoseUseOfDecl(OMD, MemberLoc))
             return ExprError();
           Selector SetterSel =
-            SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
-                                                   PP.getSelectorTable(),
+            SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
+                                                   S.PP.getSelectorTable(),
                                                    Member);
           ObjCMethodDecl *SMD = nullptr;
           if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
-                                                     /*Property id*/nullptr,
-                                                     SetterSel, Context))
+                                                     /*Property id*/ nullptr,
+                                                     SetterSel, S.Context))
             SMD = dyn_cast<ObjCMethodDecl>(SDecl);
-          
-          return Owned(new (Context) ObjCPropertyRefExpr(OMD, SMD,
-                                                         Context.PseudoObjectTy,
-                                                         VK_LValue, OK_ObjCProperty,
-                                                         MemberLoc, BaseExpr.take()));
+
+          return new (S.Context)
+              ObjCPropertyRefExpr(OMD, SMD, S.Context.PseudoObjectTy, VK_LValue,
+                                  OK_ObjCProperty, MemberLoc, BaseExpr.get());
         }
       }
       // Use of id.member can only be for a property reference. Do not
       // use the 'id' redefinition in this case.
-      if (IsArrow && ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
-        return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+      if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                                 ObjCImpDecl, HasTemplateArgs);
 
-      return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+      return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
                          << MemberName << BaseType);
     }
 
     // 'Class', unqualified only.
     if (OT->isObjCClass()) {
       // Only works in a method declaration (??!).
-      ObjCMethodDecl *MD = getCurMethodDecl();
+      ObjCMethodDecl *MD = S.getCurMethodDecl();
       if (!MD) {
-        if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
-          return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+        if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+          return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                                   ObjCImpDecl, HasTemplateArgs);
 
         goto fail;
       }
 
       // Also must look for a getter name which uses property syntax.
-      Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+      Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
       ObjCInterfaceDecl *IFace = MD->getClassInterface();
       ObjCMethodDecl *Getter;
       if ((Getter = IFace->lookupClassMethod(Sel))) {
         // Check the use of this method.
-        if (DiagnoseUseOfDecl(Getter, MemberLoc))
+        if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
           return ExprError();
       } else
         Getter = IFace->lookupPrivateMethod(Sel, false);
       // If we found a getter then this may be a valid dot-reference, we
       // will look for the matching setter, in case it is needed.
       Selector SetterSel =
-        SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
-                                               PP.getSelectorTable(),
+        SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
+                                               S.PP.getSelectorTable(),
                                                Member);
       ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
       if (!Setter) {
@@ -1502,28 +1491,27 @@
         Setter = IFace->lookupPrivateMethod(SetterSel, false);
       }
 
-      if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+      if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
         return ExprError();
 
       if (Getter || Setter) {
-        return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                       Context.PseudoObjectTy,
-                                                       VK_LValue, OK_ObjCProperty,
-                                                       MemberLoc, BaseExpr.take()));
+        return new (S.Context) ObjCPropertyRefExpr(
+            Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
+            OK_ObjCProperty, MemberLoc, BaseExpr.get());
       }
 
-      if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
-        return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+      if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                                 ObjCImpDecl, HasTemplateArgs);
 
-      return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+      return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
                          << MemberName << BaseType);
     }
 
     // Normal property access.
-    return HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, 
-                                     MemberName, MemberLoc,
-                                     SourceLocation(), QualType(), false);
+    return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName,
+                                       MemberLoc, SourceLocation(), QualType(),
+                                       false);
   }
 
   // Handle 'field access' to vectors, such as 'V.xx'.
@@ -1531,24 +1519,22 @@
     // FIXME: this expr should store IsArrow.
     IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
     ExprValueKind VK = (IsArrow ? VK_LValue : BaseExpr.get()->getValueKind());
-    QualType ret = CheckExtVectorComponent(*this, BaseType, VK, OpLoc,
+    QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
                                            Member, MemberLoc);
     if (ret.isNull())
       return ExprError();
 
-    return Owned(new (Context) ExtVectorElementExpr(ret, VK, BaseExpr.take(),
-                                                    *Member, MemberLoc));
+    return new (S.Context)
+        ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
   }
 
   // Adjust builtin-sel to the appropriate redefinition type if that's
   // not just a pointer to builtin-sel again.
-  if (IsArrow &&
-      BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
-      !Context.getObjCSelRedefinitionType()->isObjCSelType()) {
-    BaseExpr = ImpCastExprToType(BaseExpr.take(), 
-                                 Context.getObjCSelRedefinitionType(),
-                                 CK_BitCast);
-    return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+  if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
+      !S.Context.getObjCSelRedefinitionType()->isObjCSelType()) {
+    BaseExpr = S.ImpCastExprToType(
+        BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
+    return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                             ObjCImpDecl, HasTemplateArgs);
   }
 
@@ -1565,31 +1551,31 @@
   if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
     if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
         MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
-      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
-        << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
+      S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+          << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
           << FixItHint::CreateReplacement(OpLoc, "->");
 
       // Recurse as an -> access.
       IsArrow = true;
-      return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+      return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                               ObjCImpDecl, HasTemplateArgs);
     }
   }
 
   // If the user is trying to apply -> or . to a function name, it's probably
   // because they forgot parentheses to call that function.
-  if (tryToRecoverWithCall(BaseExpr,
-                           PDiag(diag::err_member_reference_needs_call),
-                           /*complain*/ false,
-                           IsArrow ? &isPointerToRecordType : &isRecordType)) {
+  if (S.tryToRecoverWithCall(
+          BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
+          /*complain*/ false,
+          IsArrow ? &isPointerToRecordType : &isRecordType)) {
     if (BaseExpr.isInvalid())
       return ExprError();
-    BaseExpr = DefaultFunctionArrayConversion(BaseExpr.take());
-    return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+    BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
+    return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                             ObjCImpDecl, HasTemplateArgs);
   }
 
-  Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
+  S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
     << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
 
   return ExprError();
@@ -1619,6 +1605,19 @@
   if (SS.isSet() && SS.isInvalid())
     return ExprError();
 
+  // The only way a reference to a destructor can be used is to
+  // immediately call it. If the next token is not a '(', produce
+  // a diagnostic and build the call now.
+  if (!HasTrailingLParen &&
+      Id.getKind() == UnqualifiedId::IK_DestructorName) {
+    ExprResult DtorAccess =
+        ActOnMemberAccessExpr(S, Base, OpLoc, OpKind, SS, TemplateKWLoc, Id,
+                              ObjCImpDecl, /*HasTrailingLParen*/true);
+    if (DtorAccess.isInvalid())
+      return DtorAccess;
+    return DiagnoseDtorReference(Id.getLocStart(), DtorAccess.get());
+  }
+
   // Warn about the explicit constructor calls Microsoft extension.
   if (getLangOpts().MicrosoftExt &&
       Id.getKind() == UnqualifiedId::IK_ConstructorName)
@@ -1642,48 +1641,20 @@
   // This is a postfix expression, so get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
   if (Result.isInvalid()) return ExprError();
-  Base = Result.take();
+  Base = Result.get();
 
   if (Base->getType()->isDependentType() || Name.isDependentName() ||
       isDependentScopeSpecifier(SS)) {
-    Result = ActOnDependentMemberExpr(Base, Base->getType(),
-                                      IsArrow, OpLoc,
-                                      SS, TemplateKWLoc, FirstQualifierInScope,
-                                      NameInfo, TemplateArgs);
-  } else {
-    LookupResult R(*this, NameInfo, LookupMemberName);
-    ExprResult BaseResult = Owned(Base);
-    Result = LookupMemberExpr(R, BaseResult, IsArrow, OpLoc,
-                              SS, ObjCImpDecl, TemplateArgs != nullptr);
-    if (BaseResult.isInvalid())
-      return ExprError();
-    Base = BaseResult.take();
-
-    if (Result.isInvalid()) {
-      Owned(Base);
-      return ExprError();
-    }
-
-    if (Result.get()) {
-      // The only way a reference to a destructor can be used is to
-      // immediately call it, which falls into this case.  If the
-      // next token is not a '(', produce a diagnostic and build the
-      // call now.
-      if (!HasTrailingLParen &&
-          Id.getKind() == UnqualifiedId::IK_DestructorName)
-        return DiagnoseDtorReference(NameInfo.getLoc(), Result.get());
-
-      return Result;
-    }
-
-    ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl, HasTrailingLParen};
-    Result = BuildMemberReferenceExpr(Base, Base->getType(),
-                                      OpLoc, IsArrow, SS, TemplateKWLoc,
-                                      FirstQualifierInScope, R, TemplateArgs,
-                                      false, &ExtraArgs);
+    return ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS,
+                                    TemplateKWLoc, FirstQualifierInScope,
+                                    NameInfo, TemplateArgs);
   }
 
-  return Result;
+  ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl,
+                                          HasTrailingLParen};
+  return BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS,
+                                  TemplateKWLoc, FirstQualifierInScope,
+                                  NameInfo, TemplateArgs, &ExtraArgs);
 }
 
 static ExprResult
@@ -1742,10 +1713,9 @@
                                   FoundDecl, Field);
   if (Base.isInvalid())
     return ExprError();
-  return S.Owned(BuildMemberExpr(S, S.Context, Base.take(), IsArrow, SS,
-                                 /*TemplateKWLoc=*/SourceLocation(),
-                                 Field, FoundDecl, MemberNameInfo,
-                                 MemberType, VK, OK));
+  return BuildMemberExpr(S, S.Context, Base.get(), IsArrow, SS,
+                         /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
+                         MemberNameInfo, MemberType, VK, OK);
 }
 
 /// Builds an implicit member access expression.  The current context
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index d9e2828..5002332 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -291,12 +291,12 @@
     return ExprError();
 
   // Convert the number to the type that the parameter expects.
-  ParmVarDecl *ParamDecl = Method->param_begin()[0];
+  ParmVarDecl *ParamDecl = Method->parameters()[0];
   InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
                                                                     ParamDecl);
   ExprResult ConvertedNumber = PerformCopyInitialization(Entity,
                                                          SourceLocation(),
-                                                         Owned(Number));
+                                                         Number);
   if (ConvertedNumber.isInvalid())
     return ExprError();
   Number = ConvertedNumber.get();
@@ -445,7 +445,7 @@
   if (ValueExpr->isTypeDependent()) {
     ObjCBoxedExpr *BoxedExpr = 
       new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR);
-    return Owned(BoxedExpr);
+    return BoxedExpr;
   }
   ObjCMethodDecl *BoxingMethod = nullptr;
   QualType BoxedType;
@@ -555,7 +555,7 @@
         break;
       }
     }
-    
+    CheckForIntOverflow(ValueExpr);
     // FIXME:  Do I need to do anything special with BoolTy expressions?
     
     // Look for the appropriate method within NSNumber.
@@ -581,12 +581,12 @@
   }
   
   // Convert the expression to the type that the parameter requires.
-  ParmVarDecl *ParamDecl = BoxingMethod->param_begin()[0];
+  ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0];
   InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
                                                                     ParamDecl);
   ExprResult ConvertedValueExpr = PerformCopyInitialization(Entity,
                                                             SourceLocation(),
-                                                            Owned(ValueExpr));
+                                                            ValueExpr);
   if (ConvertedValueExpr.isInvalid())
     return ExprError();
   ValueExpr = ConvertedValueExpr.get();
@@ -624,13 +624,9 @@
   BaseExpr = Result.get();
 
   // Build the pseudo-object expression.
-  return Owned(ObjCSubscriptRefExpr::Create(Context, 
-                                            BaseExpr,
-                                            IndexExpr,
-                                            Context.PseudoObjectTy,
-                                            getterMethod,
-                                            setterMethod, RB));
-  
+  return ObjCSubscriptRefExpr::Create(Context, BaseExpr, IndexExpr,
+                                      Context.PseudoObjectTy, getterMethod,
+                                      setterMethod, RB);
 }
 
 ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
@@ -693,13 +689,13 @@
       return ExprError();
 
     // Dig out the type that all elements should be converted to.
-    QualType T = Method->param_begin()[0]->getType();
+    QualType T = Method->parameters()[0]->getType();
     const PointerType *PtrT = T->getAs<PointerType>();
     if (!PtrT || 
         !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {
       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
         << Sel;
-      Diag(Method->param_begin()[0]->getLocation(),
+      Diag(Method->parameters()[0]->getLocation(),
            diag::note_objc_literal_method_param)
         << 0 << T 
         << Context.getPointerType(IdT.withConst());
@@ -707,13 +703,13 @@
     }
   
     // Check that the 'count' parameter is integral.
-    if (!Method->param_begin()[1]->getType()->isIntegerType()) {
+    if (!Method->parameters()[1]->getType()->isIntegerType()) {
       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
         << Sel;
-      Diag(Method->param_begin()[1]->getLocation(),
+      Diag(Method->parameters()[1]->getLocation(),
            diag::note_objc_literal_method_param)
         << 1 
-        << Method->param_begin()[1]->getType()
+        << Method->parameters()[1]->getType()
         << "integral";
       return ExprError();
     }
@@ -722,7 +718,7 @@
     ArrayWithObjectsMethod = Method;
   }
 
-  QualType ObjectsType = ArrayWithObjectsMethod->param_begin()[0]->getType();
+  QualType ObjectsType = ArrayWithObjectsMethod->parameters()[0]->getType();
   QualType RequiredType = ObjectsType->castAs<PointerType>()->getPointeeType();
 
   // Check that each of the elements provided is valid in a collection literal,
@@ -820,13 +816,13 @@
        return ExprError();
 
     // Dig out the type that all values should be converted to.
-    QualType ValueT = Method->param_begin()[0]->getType();
+    QualType ValueT = Method->parameters()[0]->getType();
     const PointerType *PtrValue = ValueT->getAs<PointerType>();
     if (!PtrValue || 
         !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
         << Sel;
-      Diag(Method->param_begin()[0]->getLocation(),
+      Diag(Method->parameters()[0]->getLocation(),
            diag::note_objc_literal_method_param)
         << 0 << ValueT
         << Context.getPointerType(IdT.withConst());
@@ -834,7 +830,7 @@
     }
 
     // Dig out the type that all keys should be converted to.
-    QualType KeyT = Method->param_begin()[1]->getType();
+    QualType KeyT = Method->parameters()[1]->getType();
     const PointerType *PtrKey = KeyT->getAs<PointerType>();
     if (!PtrKey || 
         !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
@@ -860,7 +856,7 @@
       if (err) {
         Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
           << Sel;
-        Diag(Method->param_begin()[1]->getLocation(),
+        Diag(Method->parameters()[1]->getLocation(),
              diag::note_objc_literal_method_param)
           << 1 << KeyT
           << Context.getPointerType(IdT.withConst());
@@ -869,11 +865,11 @@
     }
 
     // Check that the 'count' parameter is integral.
-    QualType CountType = Method->param_begin()[2]->getType();
+    QualType CountType = Method->parameters()[2]->getType();
     if (!CountType->isIntegerType()) {
       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
         << Sel;
-      Diag(Method->param_begin()[2]->getLocation(),
+      Diag(Method->parameters()[2]->getLocation(),
            diag::note_objc_literal_method_param)
         << 2 << CountType
         << "integral";
@@ -884,9 +880,9 @@
     DictionaryWithObjectsMethod = Method;
   }
 
-  QualType ValuesT = DictionaryWithObjectsMethod->param_begin()[0]->getType();
+  QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();
   QualType ValueT = ValuesT->castAs<PointerType>()->getPointeeType();
-  QualType KeysT = DictionaryWithObjectsMethod->param_begin()[1]->getType();
+  QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();
   QualType KeyT = KeysT->castAs<PointerType>()->getPointeeType();
 
   // Check that each of the keys and values provided is valid in a collection 
@@ -980,6 +976,8 @@
 
 static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
                                                SourceLocation AtLoc,
+                                               SourceLocation LParenLoc,
+                                               SourceLocation RParenLoc,
                                                ObjCMethodDecl *Method,
                                                ObjCMethodList &MethList) {
   ObjCMethodList *M = &MethList;
@@ -995,7 +993,8 @@
       if (!Warned) {
         Warned = true;
         S.Diag(AtLoc, diag::warning_multiple_selectors)
-          << Method->getSelector();
+          << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")
+          << FixItHint::CreateInsertion(RParenLoc, ")");
         S.Diag(Method->getLocation(), diag::note_method_declared_at)
           << Method->getDeclName();
       }
@@ -1007,25 +1006,26 @@
 }
 
 static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,
-                                        ObjCMethodDecl *Method) {
-  if (S.Diags.getDiagnosticLevel(diag::warning_multiple_selectors,
-                                 SourceLocation())
-        == DiagnosticsEngine::Ignored)
+                                        ObjCMethodDecl *Method,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation RParenLoc,
+                                        bool WarnMultipleSelectors) {
+  if (!WarnMultipleSelectors ||
+      S.Diags.isIgnored(diag::warning_multiple_selectors, SourceLocation()))
     return;
   bool Warned = false;
   for (Sema::GlobalMethodPool::iterator b = S.MethodPool.begin(),
        e = S.MethodPool.end(); b != e; b++) {
     // first, instance methods
     ObjCMethodList &InstMethList = b->second.first;
-    if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc,
+    if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
                                                       Method, InstMethList))
       Warned = true;
         
     // second, class methods
     ObjCMethodList &ClsMethList = b->second.second;
-    if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc,
-                                                      Method, ClsMethList) ||
-        Warned)
+    if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
+                                                      Method, ClsMethList) || Warned)
       return;
   }
 }
@@ -1034,7 +1034,8 @@
                                              SourceLocation AtLoc,
                                              SourceLocation SelLoc,
                                              SourceLocation LParenLoc,
-                                             SourceLocation RParenLoc) {
+                                             SourceLocation RParenLoc,
+                                             bool WarnMultipleSelectors) {
   ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
                              SourceRange(LParenLoc, RParenLoc), false, false);
   if (!Method)
@@ -1052,7 +1053,8 @@
     } else
         Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
   } else
-    DiagnoseMismatchedSelectors(*this, AtLoc, Method);
+    DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc,
+                                WarnMultipleSelectors);
   
   if (Method &&
       Method->getImplementationControl() != ObjCMethodDecl::Optional &&
@@ -1296,7 +1298,7 @@
       }
       if (result.isInvalid())
         return true;
-      Args[i] = result.take();
+      Args[i] = result.get();
     }
 
     unsigned DiagID;
@@ -1366,7 +1368,7 @@
 
     Expr *argExpr = Args[i];
 
-    ParmVarDecl *param = Method->param_begin()[i];
+    ParmVarDecl *param = Method->parameters()[i];
     assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
 
     // Strip the unbridged-cast placeholder expression off unless it's
@@ -1383,7 +1385,7 @@
       if (argE.isInvalid()) {
         IsError = true;
       } else {
-        Args[i] = argE.take();
+        Args[i] = argE.get();
 
         // Update the parameter type in-place.
         param->setType(paramType);
@@ -1398,11 +1400,11 @@
 
     InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
                                                                       param);
-    ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, Owned(argExpr));
+    ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, argExpr);
     if (ArgE.isInvalid())
       IsError = true;
     else
-      Args[i] = ArgE.takeAs<Expr>();
+      Args[i] = ArgE.getAs<Expr>();
   }
 
   // Promote additional arguments to variadic methods.
@@ -1414,7 +1416,7 @@
       ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod,
                                                         nullptr);
       IsError |= Arg.isInvalid();
-      Args[i] = Arg.take();
+      Args[i] = Arg.get();
     }
   } else {
     // Check for extra arguments to non-variadic methods.
@@ -1583,14 +1585,13 @@
     if (DiagnoseUseOfDecl(PD, MemberLoc))
       return ExprError();
     if (Super)
-      return Owned(new (Context) ObjCPropertyRefExpr(PD, Context.PseudoObjectTy,
-                                                     VK_LValue, OK_ObjCProperty,
-                                                     MemberLoc, 
-                                                     SuperLoc, SuperType));
+      return new (Context)
+          ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
     else
-      return Owned(new (Context) ObjCPropertyRefExpr(PD, Context.PseudoObjectTy,
-                                                     VK_LValue, OK_ObjCProperty,
-                                                     MemberLoc, BaseExpr));
+      return new (Context)
+          ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, MemberLoc, BaseExpr);
   }
   // Check protocols on qualified interfaces.
   for (const auto *I : OPT->quals())
@@ -1600,19 +1601,13 @@
         return ExprError();
 
       if (Super)
-        return Owned(new (Context) ObjCPropertyRefExpr(PD,
-                                                       Context.PseudoObjectTy,
-                                                       VK_LValue,
-                                                       OK_ObjCProperty,
-                                                       MemberLoc, 
-                                                       SuperLoc, SuperType));
+        return new (Context) ObjCPropertyRefExpr(
+            PD, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty, MemberLoc,
+            SuperLoc, SuperType);
       else
-        return Owned(new (Context) ObjCPropertyRefExpr(PD,
-                                                       Context.PseudoObjectTy,
-                                                       VK_LValue,
-                                                       OK_ObjCProperty,
-                                                       MemberLoc,
-                                                       BaseExpr));
+        return new (Context)
+            ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+                                OK_ObjCProperty, MemberLoc, BaseExpr);
     }
   // If that failed, look for an "implicit" property by seeing if the nullary
   // selector is implemented.
@@ -1658,16 +1653,13 @@
 
   if (Getter || Setter) {
     if (Super)
-      return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                     Context.PseudoObjectTy,
-                                                     VK_LValue, OK_ObjCProperty,
-                                                     MemberLoc,
-                                                     SuperLoc, SuperType));
+      return new (Context)
+          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
     else
-      return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                     Context.PseudoObjectTy,
-                                                     VK_LValue, OK_ObjCProperty,
-                                                     MemberLoc, BaseExpr));
+      return new (Context)
+          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, MemberLoc, BaseExpr);
 
   }
 
@@ -1798,18 +1790,14 @@
 
   if (Getter || Setter) {
     if (IsSuper)
-    return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                   Context.PseudoObjectTy,
-                                                   VK_LValue, OK_ObjCProperty,
-                                                   propertyNameLoc,
-                                                   receiverNameLoc, 
-                                          Context.getObjCInterfaceType(IFace)));
+      return new (Context)
+          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, propertyNameLoc, receiverNameLoc,
+                              Context.getObjCInterfaceType(IFace));
 
-    return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                   Context.PseudoObjectTy,
-                                                   VK_LValue, OK_ObjCProperty,
-                                                   propertyNameLoc,
-                                                   receiverNameLoc, IFace));
+    return new (Context) ObjCPropertyRefExpr(
+        Getter, Setter, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty,
+        propertyNameLoc, receiverNameLoc, IFace);
   }
   return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
                      << &propertyName << Context.getObjCInterfaceType(IFace));
@@ -2007,7 +1995,7 @@
                                bool (*refactor)(const ObjCMessageExpr *,
                                               const NSAPI &, edit::Commit &)) {
   SourceLocation MsgLoc = Msg->getExprLoc();
-  if (S.Diags.getDiagnosticLevel(DiagID, MsgLoc) == DiagnosticsEngine::Ignored)
+  if (S.Diags.isIgnored(DiagID, MsgLoc))
     return;
 
   SourceManager &SM = S.SourceMgr;
@@ -2103,11 +2091,10 @@
     unsigned NumArgs = ArgsIn.size();
     Expr **Args = ArgsIn.data();
     assert(SuperLoc.isInvalid() && "Message to super with dependent type");
-    return Owned(ObjCMessageExpr::Create(Context, ReceiverType,
-                                         VK_RValue, LBracLoc, ReceiverTypeInfo,
-                                         Sel, SelectorLocs, /*Method=*/nullptr,
-                                         makeArrayRef(Args, NumArgs),RBracLoc,
-                                         isImplicit));
+    return ObjCMessageExpr::Create(
+        Context, ReceiverType, VK_RValue, LBracLoc, ReceiverTypeInfo, Sel,
+        SelectorLocs, /*Method=*/nullptr, makeArrayRef(Args, NumArgs), RBracLoc,
+        isImplicit);
   }
   
   // Find the class to which we are sending this message.
@@ -2288,7 +2275,7 @@
       else
         Result = CheckPlaceholderExpr(Receiver);
       if (Result.isInvalid()) return ExprError();
-      Receiver = Result.take();
+      Receiver = Result.get();
     }
 
     if (Receiver->isTypeDependent()) {
@@ -2297,11 +2284,10 @@
       unsigned NumArgs = ArgsIn.size();
       Expr **Args = ArgsIn.data();
       assert(SuperLoc.isInvalid() && "Message to super with dependent type");
-      return Owned(ObjCMessageExpr::Create(Context, Context.DependentTy,
-                                           VK_RValue, LBracLoc, Receiver, Sel, 
-                                           SelectorLocs, /*Method=*/nullptr,
-                                           makeArrayRef(Args, NumArgs),
-                                           RBracLoc, isImplicit));
+      return ObjCMessageExpr::Create(
+          Context, Context.DependentTy, VK_RValue, LBracLoc, Receiver, Sel,
+          SelectorLocs, /*Method=*/nullptr, makeArrayRef(Args, NumArgs),
+          RBracLoc, isImplicit);
     }
 
     // If necessary, apply function/array conversion to the receiver.
@@ -2309,7 +2295,7 @@
     ExprResult Result = DefaultFunctionArrayLvalueConversion(Receiver);
     if (Result.isInvalid())
       return ExprError();
-    Receiver = Result.take();
+    Receiver = Result.get();
     ReceiverType = Receiver->getType();
 
     // If the receiver is an ObjC pointer, a block pointer, or an
@@ -2328,14 +2314,14 @@
         << Receiver->getSourceRange();
       if (ReceiverType->isPointerType()) {
         Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(), 
-                                     CK_CPointerToObjCPointerCast).take();
+                                     CK_CPointerToObjCPointerCast).get();
       } else {
         // TODO: specialized warning on null receivers?
         bool IsNull = Receiver->isNullPointerConstant(Context,
                                               Expr::NPC_ValueDependentIsNull);
         CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
         Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
-                                     Kind).take();
+                                     Kind).get();
       }
       ReceiverType = Receiver->getType();
     } else if (getLangOpts().CPlusPlus) {
@@ -2346,7 +2332,7 @@
 
       ExprResult result = PerformContextuallyConvertToObjCPointer(Receiver);
       if (result.isUsable()) {
-        Receiver = result.take();
+        Receiver = result.get();
         ReceiverType = Receiver->getType();
       }
     }
@@ -2662,7 +2648,14 @@
   }
 
   if (getLangOpts().ObjCAutoRefCount) {
-    DiagnoseARCUseOfWeakReceiver(*this, Receiver);
+    // Do not warn about IBOutlet weak property receivers being set to null
+    // as this cannot asynchronously happen.
+    bool WarnWeakReceiver = true;
+    if (isImplicit && Method)
+      if (const ObjCPropertyDecl *PropertyDecl = Method->findPropertyDecl())
+        WarnWeakReceiver = !PropertyDecl->hasAttr<IBOutletAttr>();
+    if (WarnWeakReceiver)
+      DiagnoseARCUseOfWeakReceiver(*this, Receiver);
     
     // In ARC, annotate delegate init calls.
     if (Result->getMethodFamily() == OMF_init &&
@@ -2674,7 +2667,7 @@
         // The implicit assignment to self means we also don't want to
         // consume the result.
         Result->setDelegateInitCall(true);
-        return Owned(Result);
+        return Result;
       }
     }
 
@@ -2688,15 +2681,9 @@
           Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak;
         if (!IsWeak && Sel.isUnarySelector())
           IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
-
-        if (IsWeak) {
-          DiagnosticsEngine::Level Level =
-            Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                     LBracLoc);
-          if (Level != DiagnosticsEngine::Ignored)
-            getCurFunction()->recordUseOfWeak(Result, Prop);
-
-        }
+        if (IsWeak &&
+            !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc))
+          getCurFunction()->recordUseOfWeak(Result, Prop);
       }
     }
   }
@@ -2733,7 +2720,7 @@
   if (isa<ParenListExpr>(Receiver)) {
     ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Receiver);
     if (Result.isInvalid()) return ExprError();
-    Receiver = Result.take();
+    Receiver = Result.get();
   }
   
   if (RespondsToSelectorSel.isNull()) {
@@ -3153,7 +3140,7 @@
   if (QT->isPointerType()) {
     QT = QT->getPointeeType();
     if (const RecordType *RT = QT->getAs<RecordType>())
-      if (RecordDecl *RD = RT->getDecl())
+      if (RecordDecl *RD = RT->getDecl()->getMostRecentDecl())
         return RD->getAttr<T>();
   }
   return nullptr;
@@ -3300,12 +3287,15 @@
 }
 
 template <typename TB>
-static void CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
+static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
+                                  bool &HadTheAttribute, bool warn) {
   QualType T = castExpr->getType();
+  HadTheAttribute = false;
   while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
     TypedefNameDecl *TDNDecl = TD->getDecl();
     if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
       if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
+        HadTheAttribute = true;
         NamedDecl *Target = nullptr;
         // Check for an existing type with this name.
         LookupResult R(S, DeclarationName(Parm), SourceLocation(),
@@ -3320,23 +3310,26 @@
                 = InterfacePointerType->getObjectType()->getInterface();
               if ((CastClass == ExprClass) ||
                   (CastClass && ExprClass->isSuperClassOf(CastClass)))
-                return;
-              S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
-                << T << Target->getName() << castType->getPointeeType();
-              return;
+                return true;
+              if (warn)
+                S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
+                  << T << Target->getName() << castType->getPointeeType();
+              return false;
             } else if (castType->isObjCIdType() ||
                        (S.Context.ObjCObjectAdoptsQTypeProtocols(
                           castType, ExprClass)))
               // ok to cast to 'id'.
               // casting to id<p-list> is ok if bridge type adopts all of
               // p-list protocols.
-              return;
+              return true;
             else {
-              S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
-                << T << Target->getName() << castType;
-              S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
-              S.Diag(Target->getLocStart(), diag::note_declared_at);
-              return;
+              if (warn) {
+                S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
+                  << T << Target->getName() << castType;
+                S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+                S.Diag(Target->getLocStart(), diag::note_declared_at);
+              }
+              return false;
            }
           }
         }
@@ -3345,20 +3338,25 @@
         S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
         if (Target)
           S.Diag(Target->getLocStart(), diag::note_declared_at);
+        return true;
       }
-      return;
+      return false;
     }
     T = TDNDecl->getUnderlyingType();
   }
+  return true;
 }
 
 template <typename TB>
-static void CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr) {
+static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr,
+                                  bool &HadTheAttribute, bool warn) {
   QualType T = castType;
+  HadTheAttribute = false;
   while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
     TypedefNameDecl *TDNDecl = TD->getDecl();
     if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
       if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
+        HadTheAttribute = true;
         NamedDecl *Target = nullptr;
         // Check for an existing type with this name.
         LookupResult R(S, DeclarationName(Parm), SourceLocation(),
@@ -3373,24 +3371,28 @@
                 = InterfacePointerType->getObjectType()->getInterface();
               if ((CastClass == ExprClass) ||
                   (ExprClass && CastClass->isSuperClassOf(ExprClass)))
-                return;
-              S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
-                << castExpr->getType()->getPointeeType() << T;
-              S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
-              return;
+                return true;
+              if (warn) {
+                S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
+                  << castExpr->getType()->getPointeeType() << T;
+                S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+              }
+              return false;
             } else if (castExpr->getType()->isObjCIdType() ||
                        (S.Context.QIdProtocolsAdoptObjCObjectProtocols(
                           castExpr->getType(), CastClass)))
               // ok to cast an 'id' expression to a CFtype.
               // ok to cast an 'id<plist>' expression to CFtype provided plist
               // adopts all of CFtype's ObjetiveC's class plist.
-              return;
+              return true;
             else {
-              S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
-                << castExpr->getType() << castType;
-              S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
-              S.Diag(Target->getLocStart(), diag::note_declared_at);
-              return;
+              if (warn) {
+                S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
+                  << castExpr->getType() << castType;
+                S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+                S.Diag(Target->getLocStart(), diag::note_declared_at);
+              }
+              return false;
             }
           }
         }
@@ -3399,11 +3401,13 @@
         S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
         if (Target)
           S.Diag(Target->getLocStart(), diag::note_declared_at);
+        return true;
       }
-      return;
+      return false;
     }
     T = TDNDecl->getUnderlyingType();
   }
+  return true;
 }
 
 void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {
@@ -3413,15 +3417,72 @@
   ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());
   ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
   if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
-    CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr);
-    CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr);
+    bool HasObjCBridgeAttr;
+    bool ObjCBridgeAttrWillNotWarn =
+      CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+                                            false);
+    if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
+      return;
+    bool HasObjCBridgeMutableAttr;
+    bool ObjCBridgeMutableAttrWillNotWarn =
+      CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+                                                   HasObjCBridgeMutableAttr, false);
+    if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
+      return;
+    
+    if (HasObjCBridgeAttr)
+      CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+                                            true);
+    else if (HasObjCBridgeMutableAttr)
+      CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+                                                   HasObjCBridgeMutableAttr, true);
   }
   else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
-    CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr);
-    CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr);
+    bool HasObjCBridgeAttr;
+    bool ObjCBridgeAttrWillNotWarn =
+      CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+                                            false);
+    if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
+      return;
+    bool HasObjCBridgeMutableAttr;
+    bool ObjCBridgeMutableAttrWillNotWarn =
+      CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+                                                   HasObjCBridgeMutableAttr, false);
+    if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
+      return;
+    
+    if (HasObjCBridgeAttr)
+      CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+                                            true);
+    else if (HasObjCBridgeMutableAttr)
+      CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+                                                   HasObjCBridgeMutableAttr, true);
   }
 }
 
+void Sema::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) {
+  QualType SrcType = castExpr->getType();
+  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) {
+    if (PRE->isExplicitProperty()) {
+      if (ObjCPropertyDecl *PDecl = PRE->getExplicitProperty())
+        SrcType = PDecl->getType();
+    }
+    else if (PRE->isImplicitProperty()) {
+      if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())
+        SrcType = Getter->getReturnType();
+      
+    }
+  }
+  
+  ARCConversionTypeClass srcExprACTC = classifyTypeForARCConversion(SrcType);
+  ARCConversionTypeClass castExprACTC = classifyTypeForARCConversion(castType);
+  if (srcExprACTC != ACTC_retainable || castExprACTC != ACTC_coreFoundation)
+    return;
+  CheckObjCBridgeRelatedConversions(castExpr->getLocStart(),
+                                    castType, SrcType, castExpr);
+  return;
+}
+
 bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
                                          CastKind &Kind) {
   if (!getLangOpts().ObjC1)
@@ -3547,7 +3608,7 @@
                                       ClassMethod->getLocation(),
                                       ClassMethod->getSelector(), ClassMethod,
                                       MultiExprArg(args, 1));
-      SrcExpr = msg.take();
+      SrcExpr = msg.get();
       return true;
     }
   }
@@ -3584,7 +3645,7 @@
                                      InstanceMethod->getLocation(),
                                      InstanceMethod->getSelector(),
                                      InstanceMethod, None);
-      SrcExpr = msg.take();
+      SrcExpr = msg.get();
       return true;
     }
   }
@@ -3594,7 +3655,8 @@
 Sema::ARCConversionResult
 Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
                              Expr *&castExpr, CheckedConversionKind CCK,
-                             bool DiagnoseCFAudited) {
+                             bool DiagnoseCFAudited,
+                             BinaryOperatorKind Opc) {
   QualType castExprType = castExpr->getType();
 
   // For the purposes of the classification, we assume reference types
@@ -3688,8 +3750,10 @@
   // instead.
   if (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
       castACTC != ACTC_coreFoundation)
-    diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
-                              castExpr, castExpr, exprACTC, CCK);
+    if (!(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
+          (Opc == BO_NE || Opc == BO_EQ)))
+      diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
+                                castExpr, castExpr, exprACTC, CCK);
   return ACR_okay;
 }
 
@@ -3806,7 +3870,7 @@
                                       Expr *SubExpr) {
   ExprResult SubResult = UsualUnaryConversions(SubExpr);
   if (SubResult.isInvalid()) return ExprError();
-  SubExpr = SubResult.take();
+  SubExpr = SubResult.get();
 
   QualType T = TSInfo->getType();
   QualType FromType = SubExpr->getType();
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index a169602..a33724a 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/SemaInternal.h"
@@ -312,15 +313,20 @@
   int numArrayElements(QualType DeclType);
   int numStructUnionElements(QualType DeclType);
 
-  void FillInValueInitForField(unsigned Init, FieldDecl *Field,
+  static ExprResult PerformEmptyInit(Sema &SemaRef,
+                                     SourceLocation Loc,
+                                     const InitializedEntity &Entity,
+                                     bool VerifyOnly);
+  void FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
                                const InitializedEntity &ParentEntity,
                                InitListExpr *ILE, bool &RequiresSecondPass);
-  void FillInValueInitializations(const InitializedEntity &Entity,
+  void FillInEmptyInitializations(const InitializedEntity &Entity,
                                   InitListExpr *ILE, bool &RequiresSecondPass);
   bool CheckFlexibleArrayInit(const InitializedEntity &Entity,
                               Expr *InitExpr, FieldDecl *Field,
                               bool TopLevelObject);
-  void CheckValueInitializable(const InitializedEntity &Entity);
+  void CheckEmptyInitializable(const InitializedEntity &Entity,
+                               SourceLocation Loc);
 
 public:
   InitListChecker(Sema &S, const InitializedEntity &Entity,
@@ -333,33 +339,134 @@
 };
 } // end anonymous namespace
 
-void InitListChecker::CheckValueInitializable(const InitializedEntity &Entity) {
-  assert(VerifyOnly &&
-         "CheckValueInitializable is only inteded for verification mode.");
-
-  SourceLocation Loc;
+ExprResult InitListChecker::PerformEmptyInit(Sema &SemaRef,
+                                             SourceLocation Loc,
+                                             const InitializedEntity &Entity,
+                                             bool VerifyOnly) {
   InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
                                                             true);
-  InitializationSequence InitSeq(SemaRef, Entity, Kind, None);
-  if (InitSeq.Failed())
+  MultiExprArg SubInit;
+  Expr *InitExpr;
+  InitListExpr DummyInitList(SemaRef.Context, Loc, None, Loc);
+
+  // C++ [dcl.init.aggr]p7:
+  //   If there are fewer initializer-clauses in the list than there are
+  //   members in the aggregate, then each member not explicitly initialized
+  //   ...
+  bool EmptyInitList = SemaRef.getLangOpts().CPlusPlus11 &&
+      Entity.getType()->getBaseElementTypeUnsafe()->isRecordType();
+  if (EmptyInitList) {
+    // C++1y / DR1070:
+    //   shall be initialized [...] from an empty initializer list.
+    //
+    // We apply the resolution of this DR to C++11 but not C++98, since C++98
+    // does not have useful semantics for initialization from an init list.
+    // We treat this as copy-initialization, because aggregate initialization
+    // always performs copy-initialization on its elements.
+    //
+    // Only do this if we're initializing a class type, to avoid filling in
+    // the initializer list where possible.
+    InitExpr = VerifyOnly ? &DummyInitList : new (SemaRef.Context)
+                   InitListExpr(SemaRef.Context, Loc, None, Loc);
+    InitExpr->setType(SemaRef.Context.VoidTy);
+    SubInit = InitExpr;
+    Kind = InitializationKind::CreateCopy(Loc, Loc);
+  } else {
+    // C++03:
+    //   shall be value-initialized.
+  }
+
+  InitializationSequence InitSeq(SemaRef, Entity, Kind, SubInit);
+  // libstdc++4.6 marks the vector default constructor as explicit in
+  // _GLIBCXX_DEBUG mode, so recover using the C++03 logic in that case.
+  // stlport does so too. Look for std::__debug for libstdc++, and for
+  // std:: for stlport.  This is effectively a compiler-side implementation of
+  // LWG2193.
+  if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() ==
+          InitializationSequence::FK_ExplicitConstructor) {
+    OverloadCandidateSet::iterator Best;
+    OverloadingResult O =
+        InitSeq.getFailedCandidateSet()
+            .BestViableFunction(SemaRef, Kind.getLocation(), Best);
+    (void)O;
+    assert(O == OR_Success && "Inconsistent overload resolution");
+    CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
+    CXXRecordDecl *R = CtorDecl->getParent();
+
+    if (CtorDecl->getMinRequiredArguments() == 0 &&
+        CtorDecl->isExplicit() && R->getDeclName() &&
+        SemaRef.SourceMgr.isInSystemHeader(CtorDecl->getLocation())) {
+
+
+      bool IsInStd = false;
+      for (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(R->getDeclContext());
+           ND && !IsInStd; ND = dyn_cast<NamespaceDecl>(ND->getParent())) {
+        if (SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND))
+          IsInStd = true;
+      }
+
+      if (IsInStd && llvm::StringSwitch<bool>(R->getName()) 
+              .Cases("basic_string", "deque", "forward_list", true)
+              .Cases("list", "map", "multimap", "multiset", true)
+              .Cases("priority_queue", "queue", "set", "stack", true)
+              .Cases("unordered_map", "unordered_set", "vector", true)
+              .Default(false)) {
+        InitSeq.InitializeFrom(
+            SemaRef, Entity,
+            InitializationKind::CreateValue(Loc, Loc, Loc, true),
+            MultiExprArg(), /*TopLevelOfInitList=*/false);
+        // Emit a warning for this.  System header warnings aren't shown
+        // by default, but people working on system headers should see it.
+        if (!VerifyOnly) {
+          SemaRef.Diag(CtorDecl->getLocation(),
+                       diag::warn_invalid_initializer_from_system_header);
+          SemaRef.Diag(Entity.getDecl()->getLocation(),
+                       diag::note_used_in_initialization_here);
+        }
+      }
+    }
+  }
+  if (!InitSeq) {
+    if (!VerifyOnly) {
+      InitSeq.Diagnose(SemaRef, Entity, Kind, SubInit);
+      if (Entity.getKind() == InitializedEntity::EK_Member)
+        SemaRef.Diag(Entity.getDecl()->getLocation(),
+                     diag::note_in_omitted_aggregate_initializer)
+          << /*field*/1 << Entity.getDecl();
+      else if (Entity.getKind() == InitializedEntity::EK_ArrayElement)
+        SemaRef.Diag(Loc, diag::note_in_omitted_aggregate_initializer)
+          << /*array element*/0 << Entity.getElementIndex();
+    }
+    return ExprError();
+  }
+
+  return VerifyOnly ? ExprResult(static_cast<Expr *>(nullptr))
+                    : InitSeq.Perform(SemaRef, Entity, Kind, SubInit);
+}
+
+void InitListChecker::CheckEmptyInitializable(const InitializedEntity &Entity,
+                                              SourceLocation Loc) {
+  assert(VerifyOnly &&
+         "CheckEmptyInitializable is only inteded for verification mode.");
+  if (PerformEmptyInit(SemaRef, Loc, Entity, /*VerifyOnly*/true).isInvalid())
     hadError = true;
 }
 
-void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
+void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
                                         const InitializedEntity &ParentEntity,
                                               InitListExpr *ILE,
                                               bool &RequiresSecondPass) {
-  SourceLocation Loc = ILE->getLocStart();
+  SourceLocation Loc = ILE->getLocEnd();
   unsigned NumInits = ILE->getNumInits();
   InitializedEntity MemberEntity
     = InitializedEntity::InitializeMember(Field, &ParentEntity);
   if (Init >= NumInits || !ILE->getInit(Init)) {
-    // If there's no explicit initializer but we have a default initializer, use
-    // that. This only happens in C++1y, since classes with default
-    // initializers are not aggregates in C++11.
+    // C++1y [dcl.init.aggr]p7:
+    //   If there are fewer initializer-clauses in the list than there are
+    //   members in the aggregate, then each member not explicitly initialized
+    //   shall be initialized from its brace-or-equal-initializer [...]
     if (Field->hasInClassInitializer()) {
-      Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context,
-                                             ILE->getRBraceLoc(), Field);
+      Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context, Loc, Field);
       if (Init < NumInits)
         ILE->setInit(Init, DIE);
       else {
@@ -369,9 +476,6 @@
       return;
     }
 
-    // FIXME: We probably don't need to handle references
-    // specially here, since value-initialization of references is
-    // handled in InitializationSequence.
     if (Field->getType()->isReferenceType()) {
       // C++ [dcl.init.aggr]p9:
       //   If an incomplete or empty initializer-list leaves a
@@ -386,17 +490,8 @@
       return;
     }
 
-    InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
-                                                              true);
-    InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, None);
-    if (!InitSeq) {
-      InitSeq.Diagnose(SemaRef, MemberEntity, Kind, None);
-      hadError = true;
-      return;
-    }
-
-    ExprResult MemberInit
-      = InitSeq.Perform(SemaRef, MemberEntity, Kind, None);
+    ExprResult MemberInit = PerformEmptyInit(SemaRef, Loc, MemberEntity,
+                                             /*VerifyOnly*/false);
     if (MemberInit.isInvalid()) {
       hadError = true;
       return;
@@ -405,18 +500,18 @@
     if (hadError) {
       // Do nothing
     } else if (Init < NumInits) {
-      ILE->setInit(Init, MemberInit.takeAs<Expr>());
-    } else if (InitSeq.isConstructorInitialization()) {
-      // Value-initialization requires a constructor call, so
+      ILE->setInit(Init, MemberInit.getAs<Expr>());
+    } else if (!isa<ImplicitValueInitExpr>(MemberInit.get())) {
+      // Empty initialization requires a constructor call, so
       // extend the initializer list to include the constructor
       // call and make a note that we'll need to take another pass
       // through the initializer list.
-      ILE->updateInit(SemaRef.Context, Init, MemberInit.takeAs<Expr>());
+      ILE->updateInit(SemaRef.Context, Init, MemberInit.getAs<Expr>());
       RequiresSecondPass = true;
     }
   } else if (InitListExpr *InnerILE
                = dyn_cast<InitListExpr>(ILE->getInit(Init)))
-    FillInValueInitializations(MemberEntity, InnerILE,
+    FillInEmptyInitializations(MemberEntity, InnerILE,
                                RequiresSecondPass);
 }
 
@@ -424,25 +519,22 @@
 /// with expressions that perform value-initialization of the
 /// appropriate type.
 void
-InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
+InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
                                             InitListExpr *ILE,
                                             bool &RequiresSecondPass) {
   assert((ILE->getType() != SemaRef.Context.VoidTy) &&
          "Should not have void type");
-  SourceLocation Loc = ILE->getLocStart();
-  if (ILE->getSyntacticForm())
-    Loc = ILE->getSyntacticForm()->getLocStart();
 
   if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
     const RecordDecl *RDecl = RType->getDecl();
     if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())
-      FillInValueInitForField(0, ILE->getInitializedFieldInUnion(),
+      FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(),
                               Entity, ILE, RequiresSecondPass);
     else if (RDecl->isUnion() && isa<CXXRecordDecl>(RDecl) &&
              cast<CXXRecordDecl>(RDecl)->hasInClassInitializer()) {
       for (auto *Field : RDecl->fields()) {
         if (Field->hasInClassInitializer()) {
-          FillInValueInitForField(0, Field, Entity, ILE, RequiresSecondPass);
+          FillInEmptyInitForField(0, Field, Entity, ILE, RequiresSecondPass);
           break;
         }
       }
@@ -455,7 +547,7 @@
         if (hadError)
           return;
 
-        FillInValueInitForField(Init, Field, Entity, ILE, RequiresSecondPass);
+        FillInEmptyInitForField(Init, Field, Entity, ILE, RequiresSecondPass);
         if (hadError)
           return;
 
@@ -489,7 +581,6 @@
   } else
     ElementType = ILE->getType();
 
-
   for (unsigned Init = 0; Init != NumElements; ++Init) {
     if (hadError)
       return;
@@ -500,17 +591,9 @@
 
     Expr *InitExpr = (Init < NumInits ? ILE->getInit(Init) : nullptr);
     if (!InitExpr && !ILE->hasArrayFiller()) {
-      InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
-                                                                true);
-      InitializationSequence InitSeq(SemaRef, ElementEntity, Kind, None);
-      if (!InitSeq) {
-        InitSeq.Diagnose(SemaRef, ElementEntity, Kind, None);
-        hadError = true;
-        return;
-      }
-
-      ExprResult ElementInit
-        = InitSeq.Perform(SemaRef, ElementEntity, Kind, None);
+      ExprResult ElementInit = PerformEmptyInit(SemaRef, ILE->getLocEnd(),
+                                                ElementEntity,
+                                                /*VerifyOnly*/false);
       if (ElementInit.isInvalid()) {
         hadError = true;
         return;
@@ -522,29 +605,29 @@
         // For arrays, just set the expression used for value-initialization
         // of the "holes" in the array.
         if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement)
-          ILE->setArrayFiller(ElementInit.takeAs<Expr>());
+          ILE->setArrayFiller(ElementInit.getAs<Expr>());
         else
-          ILE->setInit(Init, ElementInit.takeAs<Expr>());
+          ILE->setInit(Init, ElementInit.getAs<Expr>());
       } else {
         // For arrays, just set the expression used for value-initialization
         // of the rest of elements and exit.
         if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement) {
-          ILE->setArrayFiller(ElementInit.takeAs<Expr>());
+          ILE->setArrayFiller(ElementInit.getAs<Expr>());
           return;
         }
 
-        if (InitSeq.isConstructorInitialization()) {
-          // Value-initialization requires a constructor call, so
+        if (!isa<ImplicitValueInitExpr>(ElementInit.get())) {
+          // Empty initialization requires a constructor call, so
           // extend the initializer list to include the constructor
           // call and make a note that we'll need to take another pass
           // through the initializer list.
-          ILE->updateInit(SemaRef.Context, Init, ElementInit.takeAs<Expr>());
+          ILE->updateInit(SemaRef.Context, Init, ElementInit.getAs<Expr>());
           RequiresSecondPass = true;
         }
       }
     } else if (InitListExpr *InnerILE
                  = dyn_cast_or_null<InitListExpr>(InitExpr))
-      FillInValueInitializations(ElementEntity, InnerILE, RequiresSecondPass);
+      FillInEmptyInitializations(ElementEntity, InnerILE, RequiresSecondPass);
   }
 }
 
@@ -562,9 +645,9 @@
 
   if (!hadError && !VerifyOnly) {
     bool RequiresSecondPass = false;
-    FillInValueInitializations(Entity, FullyStructuredList, RequiresSecondPass);
+    FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass);
     if (RequiresSecondPass && !hadError)
-      FillInValueInitializations(Entity, FullyStructuredList,
+      FillInEmptyInitializations(Entity, FullyStructuredList,
                                  RequiresSecondPass);
   }
 }
@@ -673,7 +756,6 @@
                                             InitListExpr *IList, QualType &T,
                                             InitListExpr *StructuredList,
                                             bool TopLevelObject) {
-  assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
   if (!VerifyOnly) {
     SyntacticToSemantic[IList] = StructuredList;
     StructuredList->setSyntacticForm(IList);
@@ -878,7 +960,7 @@
           hadError = true;
 
         UpdateStructuredListElement(StructuredList, StructuredIndex,
-                                    Result.takeAs<Expr>());
+                                    Result.getAs<Expr>());
       }
       ++Index;
       return;
@@ -894,7 +976,7 @@
     //   compatible structure or union type. In the latter case, the
     //   initial value of the object, including unnamed members, is
     //   that of the expression.
-    ExprResult ExprRes = SemaRef.Owned(expr);
+    ExprResult ExprRes = expr;
     if ((ElemType->isRecordType() || ElemType->isVectorType()) &&
         SemaRef.CheckSingleAssignmentConstraints(ElemType, ExprRes,
                                                  !VerifyOnly)
@@ -902,16 +984,16 @@
       if (ExprRes.isInvalid())
         hadError = true;
       else {
-        ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.take());
+        ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.get());
           if (ExprRes.isInvalid())
             hadError = true;
       }
       UpdateStructuredListElement(StructuredList, StructuredIndex,
-                                  ExprRes.takeAs<Expr>());
+                                  ExprRes.getAs<Expr>());
       ++Index;
       return;
     }
-    ExprRes.release();
+    ExprRes.get();
     // Fall through for subaggregate initialization
   }
 
@@ -930,8 +1012,7 @@
     if (!VerifyOnly) {
       // We cannot initialize this element, so let
       // PerformCopyInitialization produce the appropriate diagnostic.
-      SemaRef.PerformCopyInitialization(Entity, SourceLocation(),
-                                        SemaRef.Owned(expr),
+      SemaRef.PerformCopyInitialization(Entity, SourceLocation(), expr,
                                         /*TopLevelOfInitList=*/true);
     }
     hadError = true;
@@ -1019,15 +1100,14 @@
   }
 
   if (VerifyOnly) {
-    if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(expr)))
+    if (!SemaRef.CanPerformCopyInitialization(Entity,expr))
       hadError = true;
     ++Index;
     return;
   }
 
   ExprResult Result =
-    SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
-                                      SemaRef.Owned(expr),
+    SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(), expr,
                                       /*TopLevelOfInitList=*/true);
 
   Expr *ResultExpr = nullptr;
@@ -1035,7 +1115,7 @@
   if (Result.isInvalid())
     hadError = true; // types weren't compatible.
   else {
-    ResultExpr = Result.takeAs<Expr>();
+    ResultExpr = Result.getAs<Expr>();
 
     if (ResultExpr != expr) {
       // The type was promoted, update initializer list.
@@ -1082,21 +1162,20 @@
   }
 
   if (VerifyOnly) {
-    if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(expr)))
+    if (!SemaRef.CanPerformCopyInitialization(Entity,expr))
       hadError = true;
     ++Index;
     return;
   }
 
   ExprResult Result =
-    SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
-                                      SemaRef.Owned(expr),
-                                      /*TopLevelOfInitList=*/true);
+      SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(), expr,
+                                        /*TopLevelOfInitList=*/true);
 
   if (Result.isInvalid())
     hadError = true;
 
-  expr = Result.takeAs<Expr>();
+  expr = Result.getAs<Expr>();
   IList->setInit(Index, expr);
 
   if (hadError)
@@ -1119,8 +1198,9 @@
   if (Index >= IList->getNumInits()) {
     // Make sure the element type can be value-initialized.
     if (VerifyOnly)
-      CheckValueInitializable(
-          InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity));
+      CheckEmptyInitializable(
+          InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity),
+          IList->getLocEnd());
     return;
   }
 
@@ -1130,22 +1210,21 @@
     Expr *Init = IList->getInit(Index);
     if (!isa<InitListExpr>(Init) && Init->getType()->isVectorType()) {
       if (VerifyOnly) {
-        if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(Init)))
+        if (!SemaRef.CanPerformCopyInitialization(Entity, Init))
           hadError = true;
         ++Index;
         return;
       }
 
-      ExprResult Result =
-        SemaRef.PerformCopyInitialization(Entity, Init->getLocStart(),
-                                          SemaRef.Owned(Init),
-                                          /*TopLevelOfInitList=*/true);
+  ExprResult Result =
+      SemaRef.PerformCopyInitialization(Entity, Init->getLocStart(), Init,
+                                        /*TopLevelOfInitList=*/true);
 
       Expr *ResultExpr = nullptr;
       if (Result.isInvalid())
         hadError = true; // types weren't compatible.
       else {
-        ResultExpr = Result.takeAs<Expr>();
+        ResultExpr = Result.getAs<Expr>();
 
         if (ResultExpr != Init) {
           // The type was promoted, update initializer list.
@@ -1168,7 +1247,7 @@
       // Don't attempt to go past the end of the init list
       if (Index >= IList->getNumInits()) {
         if (VerifyOnly)
-          CheckValueInitializable(ElementEntity);
+          CheckEmptyInitializable(ElementEntity, IList->getLocEnd());
         break;
       }
 
@@ -1176,6 +1255,46 @@
       CheckSubElementType(ElementEntity, IList, elementType, Index,
                           StructuredList, StructuredIndex);
     }
+
+    if (VerifyOnly)
+      return;
+
+    bool isBigEndian = SemaRef.Context.getTargetInfo().isBigEndian();
+    const VectorType *T = Entity.getType()->getAs<VectorType>();
+    if (isBigEndian && (T->getVectorKind() == VectorType::NeonVector ||
+                        T->getVectorKind() == VectorType::NeonPolyVector)) {
+      // The ability to use vector initializer lists is a GNU vector extension
+      // and is unrelated to the NEON intrinsics in arm_neon.h. On little
+      // endian machines it works fine, however on big endian machines it 
+      // exhibits surprising behaviour:
+      //
+      //   uint32x2_t x = {42, 64};
+      //   return vget_lane_u32(x, 0); // Will return 64.
+      //
+      // Because of this, explicitly call out that it is non-portable.
+      //
+      SemaRef.Diag(IList->getLocStart(),
+                   diag::warn_neon_vector_initializer_non_portable);
+
+      const char *typeCode;
+      unsigned typeSize = SemaRef.Context.getTypeSize(elementType);
+
+      if (elementType->isFloatingType())
+        typeCode = "f";
+      else if (elementType->isSignedIntegerType())
+        typeCode = "s";
+      else if (elementType->isUnsignedIntegerType())
+        typeCode = "u";
+      else
+        llvm_unreachable("Invalid element type!");
+
+      SemaRef.Diag(IList->getLocStart(),
+                   SemaRef.Context.getTypeSize(VT) > 64 ?
+                   diag::note_neon_vector_initializer_non_portable_q :
+                   diag::note_neon_vector_initializer_non_portable)
+        << typeCode << typeSize;
+    }
+
     return;
   }
 
@@ -1345,8 +1464,9 @@
     // If so, check if doing that is possible.
     // FIXME: This needs to detect holes left by designated initializers too.
     if (maxElementsKnown && elementIndex < maxElements)
-      CheckValueInitializable(InitializedEntity::InitializeElement(
-                                                  SemaRef.Context, 0, Entity));
+      CheckEmptyInitializable(InitializedEntity::InitializeElement(
+                                                  SemaRef.Context, 0, Entity),
+                              IList->getLocEnd());
   }
 }
 
@@ -1431,8 +1551,9 @@
          Field != FieldEnd; ++Field) {
       if (Field->getDeclName()) {
         if (VerifyOnly)
-          CheckValueInitializable(
-              InitializedEntity::InitializeMember(*Field, &Entity));
+          CheckEmptyInitializable(
+              InitializedEntity::InitializeMember(*Field, &Entity),
+              IList->getLocEnd());
         else
           StructuredList->setInitializedFieldInUnion(*Field);
         break;
@@ -1544,8 +1665,9 @@
     // FIXME: Should check for holes left by designated initializers too.
     for (; Field != FieldEnd && !hadError; ++Field) {
       if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer())
-        CheckValueInitializable(
-            InitializedEntity::InitializeMember(*Field, &Entity));
+        CheckEmptyInitializable(
+            InitializedEntity::InitializeMember(*Field, &Entity),
+            IList->getLocEnd());
     }
   }
 
@@ -2373,7 +2495,7 @@
       Expr *Index = static_cast<Expr *>(D.getArrayIndex());
       llvm::APSInt IndexValue;
       if (!Index->isTypeDependent() && !Index->isValueDependent())
-        Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).take();
+        Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).get();
       if (!Index)
         Invalid = true;
       else {
@@ -2396,9 +2518,9 @@
                           EndIndex->isValueDependent();
       if (!StartDependent)
         StartIndex =
-            CheckArrayDesignatorExpr(*this, StartIndex, StartValue).take();
+            CheckArrayDesignatorExpr(*this, StartIndex, StartValue).get();
       if (!EndDependent)
-        EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).take();
+        EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).get();
 
       if (!StartIndex || !EndIndex)
         Invalid = true;
@@ -2440,13 +2562,13 @@
     = DesignatedInitExpr::Create(Context,
                                  Designators.data(), Designators.size(),
                                  InitExpressions, Loc, GNUSyntax,
-                                 Init.takeAs<Expr>());
+                                 Init.getAs<Expr>());
 
   if (!getLangOpts().C99)
     Diag(DIE->getLocStart(), diag::ext_designated_init)
       << DIE->getSourceRange();
 
-  return Owned(DIE);
+  return DIE;
 }
 
 //===----------------------------------------------------------------------===//
@@ -4433,7 +4555,7 @@
         SetFailed(FK_PlaceholderType);
         return;
       }
-      Args[I] = result.take();
+      Args[I] = result.get();
     }
 
   // C++0x [dcl.init]p16:
@@ -4982,7 +5104,7 @@
 
   CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
   SmallVector<Expr*, 8> ConstructorArgs;
-  CurInit.release(); // Ownership transferred into MultiExprArg, below.
+  CurInit.get(); // Ownership transferred into MultiExprArg, below.
 
   S.CheckConstructorAccess(Loc, Constructor, Entity,
                            Best->FoundDecl.getAccess(), IsExtraneousCopy);
@@ -5010,7 +5132,7 @@
       S.BuildCXXDefaultArgExpr(Loc, Constructor, Parm);
     }
 
-    return S.Owned(CurInitExpr);
+    return CurInitExpr;
   }
 
   // Determine the arguments required to actually perform the
@@ -5030,7 +5152,7 @@
 
   // If we're supposed to bind temporaries, do so.
   if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
-    CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+    CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
   return CurInit;
 }
 
@@ -5047,8 +5169,7 @@
     return;
 
   SourceLocation Loc = getInitializationLoc(Entity, CurInitExpr);
-  if (S.Diags.getDiagnosticLevel(diag::warn_cxx98_compat_temp_copy, Loc)
-        == DiagnosticsEngine::Ignored)
+  if (S.Diags.isIgnored(diag::warn_cxx98_compat_temp_copy, Loc))
     return;
 
   // Find constructors which would have been considered.
@@ -5169,7 +5290,7 @@
       S.DefineImplicitDefaultConstructor(Loc, Constructor);
   }
 
-  ExprResult CurInit = S.Owned((Expr *)nullptr);
+  ExprResult CurInit((Expr *)nullptr);
 
   // C++ [over.match.copy]p1:
   //   - When initializing a temporary to be bound to the first parameter 
@@ -5204,13 +5325,10 @@
       ? SourceRange(LBraceLoc, RBraceLoc)
       : Kind.getParenRange();
 
-    CurInit = S.Owned(
-      new (S.Context) CXXTemporaryObjectExpr(S.Context, Constructor,
-                                             TSInfo, ConstructorArgs,
-                                             ParenOrBraceRange,
-                                             HadMultipleCandidates,
-                                             IsListInitialization,
-                                             ConstructorInitRequiresZeroInit));
+    CurInit = new (S.Context) CXXTemporaryObjectExpr(
+        S.Context, Constructor, TSInfo, ConstructorArgs, ParenOrBraceRange,
+        HadMultipleCandidates, IsListInitialization,
+        ConstructorInitRequiresZeroInit);
   } else {
     CXXConstructExpr::ConstructionKind ConstructKind =
       CXXConstructExpr::CK_Complete;
@@ -5262,7 +5380,7 @@
     return ExprError();
 
   if (shouldBindAsTemporary(Entity))
-    CurInit = S.MaybeBindToTemporary(CurInit.take());
+    CurInit = S.MaybeBindToTemporary(CurInit.get());
 
   return CurInit;
 }
@@ -5589,7 +5707,7 @@
 
   // No steps means no initialization.
   if (Steps.empty())
-    return S.Owned((Expr *)nullptr);
+    return ExprResult((Expr *)nullptr);
 
   if (S.getLangOpts().CPlusPlus11 && Entity.getType()->isReferenceType() &&
       Args.size() == 1 && isa<InitListExpr>(Args[0]) &&
@@ -5622,7 +5740,7 @@
     *ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :
                                      Entity.getType();
 
-  ExprResult CurInit = S.Owned((Expr *)nullptr);
+  ExprResult CurInit((Expr *)nullptr);
 
   // For initialization steps that start with a single initializer,
   // grab the only argument out the Args and place it into the "current"
@@ -5721,11 +5839,9 @@
               (Step->Kind == SK_CastDerivedToBaseXValue ?
                    VK_XValue :
                    VK_RValue);
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
-                                                 Step->Type,
-                                                 CK_DerivedToBase,
-                                                 CurInit.get(),
-                                                 &BasePath, VK));
+      CurInit =
+          ImplicitCastExpr::Create(S.Context, Step->Type, CK_DerivedToBase,
+                                   CurInit.get(), &BasePath, VK);
       break;
     }
 
@@ -5803,7 +5919,7 @@
            MTE->getType().isDestructedType()))
         S.ExprNeedsCleanups = true;
 
-      CurInit = S.Owned(MTE);
+      CurInit = MTE;
       break;
     }
 
@@ -5825,7 +5941,7 @@
         // Build a call to the selected constructor.
         SmallVector<Expr*, 8> ConstructorArgs;
         SourceLocation Loc = CurInit.get()->getLocStart();
-        CurInit.release(); // Ownership transferred into MultiExprArg, below.
+        CurInit.get(); // Ownership transferred into MultiExprArg, below.
 
         // Determine the arguments required to actually perform the constructor
         // call.
@@ -5870,7 +5986,7 @@
         // derived-to-base conversion? I believe the answer is "no", because
         // we don't want to turn off access control here for c-style casts.
         ExprResult CurInitExprRes =
-          S.PerformObjectArgumentInitialization(CurInit.take(),
+          S.PerformObjectArgumentInitialization(CurInit.get(),
                                                 /*Qualifier=*/nullptr,
                                                 FoundFn, Conversion);
         if(CurInitExprRes.isInvalid())
@@ -5904,13 +6020,11 @@
         }
       }
 
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
-                                                 CurInit.get()->getType(),
-                                                 CastKind, CurInit.get(),
-                                                 nullptr,
-                                                CurInit.get()->getValueKind()));
+      CurInit = ImplicitCastExpr::Create(S.Context, CurInit.get()->getType(),
+                                         CastKind, CurInit.get(), nullptr,
+                                         CurInit.get()->getValueKind());
       if (MaybeBindToTemp)
-        CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+        CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
       if (RequiresCopy)
         CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
                              CurInit, /*IsExtraneousCopy=*/false);
@@ -5927,17 +6041,15 @@
               (Step->Kind == SK_QualificationConversionXValue ?
                    VK_XValue :
                    VK_RValue);
-      CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type, CK_NoOp, VK);
+      CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type, CK_NoOp, VK);
       break;
     }
 
     case SK_LValueToRValue: {
       assert(CurInit.get()->isGLValue() && "cannot load from a prvalue");
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, Step->Type,
-                                                 CK_LValueToRValue,
-                                                 CurInit.take(),
-                                                 /*BasePath=*/nullptr,
-                                                 VK_RValue));
+      CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
+                                         CK_LValueToRValue, CurInit.get(),
+                                         /*BasePath=*/nullptr, VK_RValue);
       break;
     }
 
@@ -5990,10 +6102,10 @@
 
       InitListExpr *StructuredInitList =
           PerformInitList.getFullyStructuredList();
-      CurInit.release();
+      CurInit.get();
       CurInit = shouldBindAsTemporary(InitEntity)
           ? S.MaybeBindToTemporary(StructuredInitList)
-          : S.Owned(StructuredInitList);
+          : StructuredInitList;
       break;
     }
 
@@ -6023,18 +6135,18 @@
     }
 
     case SK_UnwrapInitList:
-      CurInit = S.Owned(cast<InitListExpr>(CurInit.take())->getInit(0));
+      CurInit = cast<InitListExpr>(CurInit.get())->getInit(0);
       break;
 
     case SK_RewrapInitList: {
-      Expr *E = CurInit.take();
+      Expr *E = CurInit.get();
       InitListExpr *Syntactic = Step->WrappingSyntacticList;
       InitListExpr *ILE = new (S.Context) InitListExpr(S.Context,
           Syntactic->getLBraceLoc(), E, Syntactic->getRBraceLoc());
       ILE->setSyntacticForm(Syntactic);
       ILE->setType(E->getType());
       ILE->setValueKind(E->getValueKind());
-      CurInit = S.Owned(ILE);
+      CurInit = ILE;
       break;
     }
 
@@ -6075,12 +6187,11 @@
           TSInfo = S.Context.getTrivialTypeSourceInfo(Step->Type,
                                                     Kind.getRange().getBegin());
 
-        CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(
-                              TSInfo->getType().getNonLValueExprType(S.Context),
-                                                                 TSInfo,
-                                                    Kind.getRange().getEnd()));
+        CurInit = new (S.Context) CXXScalarValueInitExpr(
+            TSInfo->getType().getNonLValueExprType(S.Context), TSInfo,
+            Kind.getRange().getEnd());
       } else {
-        CurInit = S.Owned(new (S.Context) ImplicitValueInitExpr(Step->Type));
+        CurInit = new (S.Context) ImplicitValueInitExpr(Step->Type);
       }
       break;
     }
@@ -6127,7 +6238,7 @@
     }
 
     case SK_ObjCObjectConversion:
-      CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type,
+      CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
                           CK_ObjCObjectLValueCast,
                           CurInit.get()->getValueKind());
       break;
@@ -6165,16 +6276,15 @@
     case SK_PassByIndirectCopyRestore:
     case SK_PassByIndirectRestore:
       checkIndirectCopyRestoreSource(S, CurInit.get());
-      CurInit = S.Owned(new (S.Context)
-                        ObjCIndirectCopyRestoreExpr(CurInit.take(), Step->Type,
-                                Step->Kind == SK_PassByIndirectCopyRestore));
+      CurInit = new (S.Context) ObjCIndirectCopyRestoreExpr(
+          CurInit.get(), Step->Type,
+          Step->Kind == SK_PassByIndirectCopyRestore);
       break;
 
     case SK_ProduceObjCObject:
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, Step->Type,
-                                                 CK_ARCProduceObject,
-                                                 CurInit.take(), nullptr,
-                                                 VK_RValue));
+      CurInit =
+          ImplicitCastExpr::Create(S.Context, Step->Type, CK_ARCProduceObject,
+                                   CurInit.get(), nullptr, VK_RValue);
       break;
 
     case SK_StdInitializerList: {
@@ -6197,13 +6307,12 @@
                                   ExtendingEntity->getDecl());
 
       // Wrap it in a construction of a std::initializer_list<T>.
-      CurInit = S.Owned(
-          new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE));
+      CurInit = new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE);
 
       // Bind the result, in case the library has given initializer_list a
       // non-trivial destructor.
       if (shouldBindAsTemporary(Entity))
-        CurInit = S.MaybeBindToTemporary(CurInit.take());
+        CurInit = S.MaybeBindToTemporary(CurInit.get());
       break;
     }
 
@@ -6227,7 +6336,7 @@
       assert(Step->Type->isEventT() && 
              "Event initialization on non-event type.");
 
-      CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type,
+      CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
                                     CK_ZeroToOCLEvent,
                                     CurInit.get()->getValueKind());
       break;
@@ -6543,7 +6652,8 @@
                               Args.back()->getLocEnd());
 
     if (Failure == FK_ListConstructorOverloadFailed) {
-      assert(Args.size() == 1 && "List construction from other than 1 argument.");
+      assert(Args.size() == 1 &&
+             "List construction from other than 1 argument.");
       InitListExpr *InitList = cast<InitListExpr>(Args[0]);
       Args = MultiExprArg(InitList->getInits(), InitList->getNumInits());
     }
@@ -6588,7 +6698,8 @@
               << S.Context.getTypeDeclType(Constructor->getParent())
               << /*member=*/1
               << Entity.getName();
-            S.Diag(Entity.getDecl()->getLocation(), diag::note_field_decl);
+            S.Diag(Entity.getDecl()->getLocation(),
+                   diag::note_member_declared_at);
 
             if (const RecordType *Record
                                  = Entity.getType()->getAs<RecordType>())
@@ -7101,7 +7212,7 @@
                                                            EqualLoc,
                                                            AllowExplicit);
   InitializationSequence Seq(*this, Entity, Kind, InitE, TopLevelOfInitList);
-  Init.release();
+  Init.get();
 
   ExprResult Result = Seq.Perform(*this, Entity, Kind, InitE);
 
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index ef92e7c..0cf4ed7 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -782,7 +782,7 @@
 
   if (Result.isInvalid())
     return QualType();
-  Init = Result.takeAs<Expr>();
+  Init = Result.getAs<Expr>();
 
   // The init-capture initialization is a full-expression that must be
   // processed as one before we enter the declcontext of the lambda's
@@ -793,7 +793,7 @@
   if (Result.isInvalid())
     return QualType();
 
-  Init = Result.takeAs<Expr>();
+  Init = Result.getAs<Expr>();
   return DeducedType;
 }
 
@@ -1013,7 +1013,7 @@
       if (C->InitCaptureType.get().isNull()) 
         continue;
       Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), 
-            C->Id, C->Init.take());
+            C->Id, C->Init.get());
       // C++1y [expr.prim.lambda]p11:
       //   An init-capture behaves as if it declares and explicitly
       //   captures a variable [...] whose declarative region is the
@@ -1572,7 +1572,7 @@
                                                          /*NRVO=*/false),
                       CurrentLocation, Src);
   if (!Init.isInvalid())
-    Init = ActOnFinishFullExpr(Init.take());
+    Init = ActOnFinishFullExpr(Init.get());
   
   if (Init.isInvalid())
     return ExprError();
@@ -1612,7 +1612,7 @@
                                     Src->getType(), CapVarTSI,
                                     SC_None);
   BlockDecl::Capture Capture(/*Variable=*/CapVar, /*ByRef=*/false,
-                             /*Nested=*/false, /*Copy=*/Init.take());
+                             /*Nested=*/false, /*Copy=*/Init.get());
   Block->setCaptures(Context, &Capture, &Capture + 1, 
                      /*CapturesCXXThis=*/false);
 
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index eb6366c..adb4cbf 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1723,7 +1723,7 @@
                  != Context.getCanonicalType(PathElement.Base->getType())) {
       // We found members of the given name in two subobjects of
       // different types. If the declaration sets aren't the same, this
-      // this lookup is ambiguous.
+      // lookup is ambiguous.
       if (HasOnlyStaticMembers(Path->Decls.begin(), Path->Decls.end())) {
         CXXBasePaths::paths_iterator FirstPath = Paths.begin();
         DeclContext::lookup_iterator FirstD = FirstPath->Decls.begin();
@@ -3265,151 +3265,20 @@
 // Typo correction
 //===----------------------------------------------------------------------===//
 
-namespace {
-
-typedef SmallVector<TypoCorrection, 1> TypoResultList;
-typedef llvm::StringMap<TypoResultList, llvm::BumpPtrAllocator> TypoResultsMap;
-typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
-
-static const unsigned MaxTypoDistanceResultSets = 5;
-
-class TypoCorrectionConsumer : public VisibleDeclConsumer {
-  /// \brief The name written that is a typo in the source.
-  StringRef Typo;
-
-  /// \brief The results found that have the smallest edit distance
-  /// found (so far) with the typo name.
-  ///
-  /// The pointer value being set to the current DeclContext indicates
-  /// whether there is a keyword with this name.
-  TypoEditDistanceMap CorrectionResults;
-
-  Sema &SemaRef;
-
-public:
-  explicit TypoCorrectionConsumer(Sema &SemaRef, IdentifierInfo *Typo)
-    : Typo(Typo->getName()),
-      SemaRef(SemaRef) {}
-
-  bool includeHiddenDecls() const override { return true; }
-
-  void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
-                 bool InBaseClass) override;
-  void FoundName(StringRef Name);
-  void addKeywordResult(StringRef Keyword);
-  void addName(StringRef Name, NamedDecl *ND,
-               NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
-  void addCorrection(TypoCorrection Correction);
-
-  typedef TypoResultsMap::iterator result_iterator;
-  typedef TypoEditDistanceMap::iterator distance_iterator;
-  distance_iterator begin() { return CorrectionResults.begin(); }
-  distance_iterator end()  { return CorrectionResults.end(); }
-  void erase(distance_iterator I) { CorrectionResults.erase(I); }
-  unsigned size() const { return CorrectionResults.size(); }
-  bool empty() const { return CorrectionResults.empty(); }
-
-  TypoResultList &operator[](StringRef Name) {
-    return CorrectionResults.begin()->second[Name];
-  }
-
-  unsigned getBestEditDistance(bool Normalized) {
-    if (CorrectionResults.empty())
-      return (std::numeric_limits<unsigned>::max)();
-
-    unsigned BestED = CorrectionResults.begin()->first;
-    return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
-  }
-
-  TypoResultsMap &getBestResults() {
-    return CorrectionResults.begin()->second;
-  }
-
-};
-
+static bool isCandidateViable(CorrectionCandidateCallback &CCC,
+                              TypoCorrection &Candidate) {
+  Candidate.setCallbackDistance(CCC.RankCandidate(Candidate));
+  return Candidate.getEditDistance(false) != TypoCorrection::InvalidDistance;
 }
 
-void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
-                                       DeclContext *Ctx, bool InBaseClass) {
-  // Don't consider hidden names for typo correction.
-  if (Hiding)
-    return;
-
-  // Only consider entities with identifiers for names, ignoring
-  // special names (constructors, overloaded operators, selectors,
-  // etc.).
-  IdentifierInfo *Name = ND->getIdentifier();
-  if (!Name)
-    return;
-
-  // Only consider visible declarations and declarations from modules with
-  // names that exactly match.
-  if (!LookupResult::isVisible(SemaRef, ND) && Name->getName() != Typo &&
-      !findAcceptableDecl(SemaRef, ND))
-    return;
-
-  FoundName(Name->getName());
-}
-
-void TypoCorrectionConsumer::FoundName(StringRef Name) {
-  // Compute the edit distance between the typo and the name of this
-  // entity, and add the identifier to the list of results.
-  addName(Name, nullptr);
-}
-
-void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) {
-  // Compute the edit distance between the typo and this keyword,
-  // and add the keyword to the list of results.
-  addName(Keyword, nullptr, nullptr, true);
-}
-
-void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND,
-                                     NestedNameSpecifier *NNS, bool isKeyword) {
-  // Use a simple length-based heuristic to determine the minimum possible
-  // edit distance. If the minimum isn't good enough, bail out early.
-  unsigned MinED = abs((int)Name.size() - (int)Typo.size());
-  if (MinED && Typo.size() / MinED < 3)
-    return;
-
-  // Compute an upper bound on the allowable edit distance, so that the
-  // edit-distance algorithm can short-circuit.
-  unsigned UpperBound = (Typo.size() + 2) / 3 + 1;
-  unsigned ED = Typo.edit_distance(Name, true, UpperBound);
-  if (ED >= UpperBound) return;
-
-  TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, ED);
-  if (isKeyword) TC.makeKeyword();
-  addCorrection(TC);
-}
-
-void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {
-  StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName();
-  TypoResultList &CList =
-      CorrectionResults[Correction.getEditDistance(false)][Name];
-
-  if (!CList.empty() && !CList.back().isResolved())
-    CList.pop_back();
-  if (NamedDecl *NewND = Correction.getCorrectionDecl()) {
-    std::string CorrectionStr = Correction.getAsString(SemaRef.getLangOpts());
-    for (TypoResultList::iterator RI = CList.begin(), RIEnd = CList.end();
-         RI != RIEnd; ++RI) {
-      // If the Correction refers to a decl already in the result list,
-      // replace the existing result if the string representation of Correction
-      // comes before the current result alphabetically, then stop as there is
-      // nothing more to be done to add Correction to the candidate set.
-      if (RI->getCorrectionDecl() == NewND) {
-        if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts()))
-          *RI = Correction;
-        return;
-      }
-    }
-  }
-  if (CList.empty() || Correction.isResolved())
-    CList.push_back(Correction);
-
-  while (CorrectionResults.size() > MaxTypoDistanceResultSets)
-    erase(std::prev(CorrectionResults.end()));
-}
+static void LookupPotentialTypoResult(Sema &SemaRef,
+                                      LookupResult &Res,
+                                      IdentifierInfo *Name,
+                                      Scope *S, CXXScopeSpec *SS,
+                                      DeclContext *MemberContext,
+                                      bool EnteringContext,
+                                      bool isObjCIvarLookup,
+                                      bool FindHidden);
 
 // Fill the supplied vector with the IdentifierInfo pointers for each piece of
 // the given NestedNameSpecifier (i.e. given a NestedNameSpecifier "foo::bar::",
@@ -3454,81 +3323,452 @@
 
 namespace {
 
-class SpecifierInfo {
- public:
-  DeclContext* DeclCtx;
-  NestedNameSpecifier* NameSpecifier;
-  unsigned EditDistance;
+static const unsigned MaxTypoDistanceResultSets = 5;
 
-  SpecifierInfo(DeclContext *Ctx, NestedNameSpecifier *NNS, unsigned ED)
-      : DeclCtx(Ctx), NameSpecifier(NNS), EditDistance(ED) {}
-};
+class TypoCorrectionConsumer : public VisibleDeclConsumer {
+  typedef SmallVector<TypoCorrection, 1> TypoResultList;
+  typedef llvm::StringMap<TypoResultList> TypoResultsMap;
+  typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
 
-typedef SmallVector<DeclContext*, 4> DeclContextList;
-typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
-
-class NamespaceSpecifierSet {
-  ASTContext &Context;
-  DeclContextList CurContextChain;
-  std::string CurNameSpecifier;
-  SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
-  SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
-  bool isSorted;
-
-  SpecifierInfoList Specifiers;
-  llvm::SmallSetVector<unsigned, 4> Distances;
-  llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap;
-
-  /// \brief Helper for building the list of DeclContexts between the current
-  /// context and the top of the translation unit
-  static DeclContextList BuildContextChain(DeclContext *Start);
-
-  void SortNamespaces();
-
- public:
-  NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
-                        CXXScopeSpec *CurScopeSpec)
-      : Context(Context), CurContextChain(BuildContextChain(CurContext)),
-        isSorted(false) {
-    if (NestedNameSpecifier *NNS =
-            CurScopeSpec ? CurScopeSpec->getScopeRep() : nullptr) {
-      llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
-      NNS->print(SpecifierOStream, Context.getPrintingPolicy());
-
-      getNestedNameSpecifierIdentifiers(NNS, CurNameSpecifierIdentifiers);
-    }
-    // Build the list of identifiers that would be used for an absolute
-    // (from the global context) NestedNameSpecifier referring to the current
-    // context.
-    for (DeclContextList::reverse_iterator C = CurContextChain.rbegin(),
-                                        CEnd = CurContextChain.rend();
-         C != CEnd; ++C) {
-      if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C))
-        CurContextIdentifiers.push_back(ND->getIdentifier());
-    }
-
-    // Add the global context as a NestedNameSpecifier
-    Distances.insert(1);
-    DistanceMap[1].push_back(
-        SpecifierInfo(cast<DeclContext>(Context.getTranslationUnitDecl()),
-                      NestedNameSpecifier::GlobalSpecifier(Context), 1));
+public:
+  explicit TypoCorrectionConsumer(Sema &SemaRef,
+                                  const DeclarationNameInfo &TypoName,
+                                  Sema::LookupNameKind LookupKind,
+                                  Scope *S, CXXScopeSpec *SS,
+                                  CorrectionCandidateCallback &CCC,
+                                  DeclContext *MemberContext,
+                                  bool EnteringContext)
+      : Typo(TypoName.getName().getAsIdentifierInfo()), SemaRef(SemaRef), S(S),
+        SS(SS), CorrectionValidator(CCC), MemberContext(MemberContext),
+        Result(SemaRef, TypoName, LookupKind),
+        Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
+        EnteringContext(EnteringContext), SearchNamespaces(false) {
+    Result.suppressDiagnostics();
   }
 
-  /// \brief Add the DeclContext (a namespace or record) to the set, computing
-  /// the corresponding NestedNameSpecifier and its distance in the process.
-  void AddNameSpecifier(DeclContext *Ctx);
+  bool includeHiddenDecls() const override { return true; }
 
-  typedef SpecifierInfoList::iterator iterator;
-  iterator begin() {
-    if (!isSorted) SortNamespaces();
-    return Specifiers.begin();
+  // Methods for adding potential corrections to the consumer.
+  void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
+                 bool InBaseClass) override;
+  void FoundName(StringRef Name);
+  void addKeywordResult(StringRef Keyword);
+  void addCorrection(TypoCorrection Correction);
+
+  bool empty() const { return CorrectionResults.empty(); }
+
+  /// \brief Return the list of TypoCorrections for the given identifier from
+  /// the set of corrections that have the closest edit distance, if any.
+  TypoResultList &operator[](StringRef Name) {
+    return CorrectionResults.begin()->second[Name];
   }
-  iterator end() { return Specifiers.end(); }
+
+  /// \brief Return the edit distance of the corrections that have the
+  /// closest/best edit distance from the original typop.
+  unsigned getBestEditDistance(bool Normalized) {
+    if (CorrectionResults.empty())
+      return (std::numeric_limits<unsigned>::max)();
+
+    unsigned BestED = CorrectionResults.begin()->first;
+    return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
+  }
+
+  /// \brief Set-up method to add to the consumer the set of namespaces to use
+  /// in performing corrections to nested name specifiers. This method also
+  /// implicitly adds all of the known classes in the current AST context to the
+  /// to the consumer for correcting nested name specifiers.
+  void
+  addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces);
+
+  /// \brief Return the next typo correction that passes all internal filters
+  /// and is deemed valid by the consumer's CorrectionCandidateCallback,
+  /// starting with the corrections that have the closest edit distance. An
+  /// empty TypoCorrection is returned once no more viable corrections remain
+  /// in the consumer.
+  TypoCorrection getNextCorrection();
+
+private:
+  class NamespaceSpecifierSet {
+    struct SpecifierInfo {
+      DeclContext* DeclCtx;
+      NestedNameSpecifier* NameSpecifier;
+      unsigned EditDistance;
+    };
+
+    typedef SmallVector<DeclContext*, 4> DeclContextList;
+    typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
+
+    ASTContext &Context;
+    DeclContextList CurContextChain;
+    std::string CurNameSpecifier;
+    SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
+    SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
+    bool isSorted;
+
+    SpecifierInfoList Specifiers;
+    llvm::SmallSetVector<unsigned, 4> Distances;
+    llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap;
+
+    /// \brief Helper for building the list of DeclContexts between the current
+    /// context and the top of the translation unit
+    static DeclContextList buildContextChain(DeclContext *Start);
+
+    void sortNamespaces();
+
+    unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
+                                      NestedNameSpecifier *&NNS);
+
+   public:
+    NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
+                          CXXScopeSpec *CurScopeSpec);
+
+    /// \brief Add the DeclContext (a namespace or record) to the set, computing
+    /// the corresponding NestedNameSpecifier and its distance in the process.
+    void addNameSpecifier(DeclContext *Ctx);
+
+    typedef SpecifierInfoList::iterator iterator;
+    iterator begin() {
+      if (!isSorted) sortNamespaces();
+      return Specifiers.begin();
+    }
+    iterator end() { return Specifiers.end(); }
+  };
+
+  void addName(StringRef Name, NamedDecl *ND,
+               NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
+
+  /// \brief Find any visible decls for the given typo correction candidate.
+  /// If none are found, it to the set of candidates for which qualified lookups
+  /// will be performed to find possible nested name specifier changes.
+  bool resolveCorrection(TypoCorrection &Candidate);
+
+  /// \brief Perform qualified lookups on the queued set of typo correction
+  /// candidates and add the nested name specifier changes to each candidate if
+  /// a lookup succeeds (at which point the candidate will be returned to the
+  /// main pool of potential corrections).
+  void performQualifiedLookups();
+
+  /// \brief The name written that is a typo in the source.
+  IdentifierInfo *Typo;
+
+  /// \brief The results found that have the smallest edit distance
+  /// found (so far) with the typo name.
+  ///
+  /// The pointer value being set to the current DeclContext indicates
+  /// whether there is a keyword with this name.
+  TypoEditDistanceMap CorrectionResults;
+
+  Sema &SemaRef;
+  Scope *S;
+  CXXScopeSpec *SS;
+  CorrectionCandidateCallback &CorrectionValidator;
+  DeclContext *MemberContext;
+  LookupResult Result;
+  NamespaceSpecifierSet Namespaces;
+  SmallVector<TypoCorrection, 2> QualifiedResults;
+  bool EnteringContext;
+  bool SearchNamespaces;
 };
 
 }
 
-DeclContextList NamespaceSpecifierSet::BuildContextChain(DeclContext *Start) {
+void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
+                                       DeclContext *Ctx, bool InBaseClass) {
+  // Don't consider hidden names for typo correction.
+  if (Hiding)
+    return;
+
+  // Only consider entities with identifiers for names, ignoring
+  // special names (constructors, overloaded operators, selectors,
+  // etc.).
+  IdentifierInfo *Name = ND->getIdentifier();
+  if (!Name)
+    return;
+
+  // Only consider visible declarations and declarations from modules with
+  // names that exactly match.
+  if (!LookupResult::isVisible(SemaRef, ND) && Name != Typo &&
+      !findAcceptableDecl(SemaRef, ND))
+    return;
+
+  FoundName(Name->getName());
+}
+
+void TypoCorrectionConsumer::FoundName(StringRef Name) {
+  // Compute the edit distance between the typo and the name of this
+  // entity, and add the identifier to the list of results.
+  addName(Name, nullptr);
+}
+
+void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) {
+  // Compute the edit distance between the typo and this keyword,
+  // and add the keyword to the list of results.
+  addName(Keyword, nullptr, nullptr, true);
+}
+
+void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND,
+                                     NestedNameSpecifier *NNS, bool isKeyword) {
+  // Use a simple length-based heuristic to determine the minimum possible
+  // edit distance. If the minimum isn't good enough, bail out early.
+  StringRef TypoStr = Typo->getName();
+  unsigned MinED = abs((int)Name.size() - (int)TypoStr.size());
+  if (MinED && TypoStr.size() / MinED < 3)
+    return;
+
+  // Compute an upper bound on the allowable edit distance, so that the
+  // edit-distance algorithm can short-circuit.
+  unsigned UpperBound = (TypoStr.size() + 2) / 3 + 1;
+  unsigned ED = TypoStr.edit_distance(Name, true, UpperBound);
+  if (ED >= UpperBound) return;
+
+  TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, ED);
+  if (isKeyword) TC.makeKeyword();
+  addCorrection(TC);
+}
+
+void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {
+  StringRef TypoStr = Typo->getName();
+  StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName();
+
+  // For very short typos, ignore potential corrections that have a different
+  // base identifier from the typo or which have a normalized edit distance
+  // longer than the typo itself.
+  if (TypoStr.size() < 3 &&
+      (Name != TypoStr || Correction.getEditDistance(true) > TypoStr.size()))
+    return;
+
+  // If the correction is resolved but is not viable, ignore it.
+  if (Correction.isResolved() &&
+      !isCandidateViable(CorrectionValidator, Correction))
+    return;
+
+  TypoResultList &CList =
+      CorrectionResults[Correction.getEditDistance(false)][Name];
+
+  if (!CList.empty() && !CList.back().isResolved())
+    CList.pop_back();
+  if (NamedDecl *NewND = Correction.getCorrectionDecl()) {
+    std::string CorrectionStr = Correction.getAsString(SemaRef.getLangOpts());
+    for (TypoResultList::iterator RI = CList.begin(), RIEnd = CList.end();
+         RI != RIEnd; ++RI) {
+      // If the Correction refers to a decl already in the result list,
+      // replace the existing result if the string representation of Correction
+      // comes before the current result alphabetically, then stop as there is
+      // nothing more to be done to add Correction to the candidate set.
+      if (RI->getCorrectionDecl() == NewND) {
+        if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts()))
+          *RI = Correction;
+        return;
+      }
+    }
+  }
+  if (CList.empty() || Correction.isResolved())
+    CList.push_back(Correction);
+
+  while (CorrectionResults.size() > MaxTypoDistanceResultSets)
+    CorrectionResults.erase(std::prev(CorrectionResults.end()));
+}
+
+void TypoCorrectionConsumer::addNamespaces(
+    const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces) {
+  SearchNamespaces = true;
+
+  for (auto KNPair : KnownNamespaces)
+    Namespaces.addNameSpecifier(KNPair.first);
+
+  bool SSIsTemplate = false;
+  if (NestedNameSpecifier *NNS =
+          (SS && SS->isValid()) ? SS->getScopeRep() : nullptr) {
+    if (const Type *T = NNS->getAsType())
+      SSIsTemplate = T->getTypeClass() == Type::TemplateSpecialization;
+  }
+  for (const auto *TI : SemaRef.getASTContext().types()) {
+    if (CXXRecordDecl *CD = TI->getAsCXXRecordDecl()) {
+      CD = CD->getCanonicalDecl();
+      if (!CD->isDependentType() && !CD->isAnonymousStructOrUnion() &&
+          !CD->isUnion() && CD->getIdentifier() &&
+          (SSIsTemplate || !isa<ClassTemplateSpecializationDecl>(CD)) &&
+          (CD->isBeingDefined() || CD->isCompleteDefinition()))
+        Namespaces.addNameSpecifier(CD);
+    }
+  }
+}
+
+TypoCorrection TypoCorrectionConsumer::getNextCorrection() {
+  while (!CorrectionResults.empty()) {
+    auto DI = CorrectionResults.begin();
+    if (DI->second.empty()) {
+      CorrectionResults.erase(DI);
+      continue;
+    }
+
+    auto RI = DI->second.begin();
+    if (RI->second.empty()) {
+      DI->second.erase(RI);
+      performQualifiedLookups();
+      continue;
+    }
+
+    TypoCorrection TC = RI->second.pop_back_val();
+    if (TC.isResolved() || resolveCorrection(TC))
+      return TC;
+  }
+  return TypoCorrection();
+}
+
+bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) {
+  IdentifierInfo *Name = Candidate.getCorrectionAsIdentifierInfo();
+  DeclContext *TempMemberContext = MemberContext;
+  CXXScopeSpec *TempSS = SS;
+retry_lookup:
+  LookupPotentialTypoResult(SemaRef, Result, Name, S, TempSS, TempMemberContext,
+                            EnteringContext,
+                            CorrectionValidator.IsObjCIvarLookup,
+                            Name == Typo && !Candidate.WillReplaceSpecifier());
+  switch (Result.getResultKind()) {
+  case LookupResult::NotFound:
+  case LookupResult::NotFoundInCurrentInstantiation:
+  case LookupResult::FoundUnresolvedValue:
+    if (TempSS) {
+      // Immediately retry the lookup without the given CXXScopeSpec
+      TempSS = nullptr;
+      Candidate.WillReplaceSpecifier(true);
+      goto retry_lookup;
+    }
+    if (TempMemberContext) {
+      if (SS && !TempSS)
+        TempSS = SS;
+      TempMemberContext = nullptr;
+      goto retry_lookup;
+    }
+    if (SearchNamespaces)
+      QualifiedResults.push_back(Candidate);
+    break;
+
+  case LookupResult::Ambiguous:
+    // We don't deal with ambiguities.
+    break;
+
+  case LookupResult::Found:
+  case LookupResult::FoundOverloaded:
+    // Store all of the Decls for overloaded symbols
+    for (auto *TRD : Result)
+      Candidate.addCorrectionDecl(TRD);
+    if (!isCandidateViable(CorrectionValidator, Candidate)) {
+      if (SearchNamespaces)
+        QualifiedResults.push_back(Candidate);
+      break;
+    }
+    return true;
+  }
+  return false;
+}
+
+void TypoCorrectionConsumer::performQualifiedLookups() {
+  unsigned TypoLen = Typo->getName().size();
+  for (auto QR : QualifiedResults) {
+    for (auto NSI : Namespaces) {
+      DeclContext *Ctx = NSI.DeclCtx;
+      const Type *NSType = NSI.NameSpecifier->getAsType();
+
+      // If the current NestedNameSpecifier refers to a class and the
+      // current correction candidate is the name of that class, then skip
+      // it as it is unlikely a qualified version of the class' constructor
+      // is an appropriate correction.
+      if (CXXRecordDecl *NSDecl = NSType ? NSType->getAsCXXRecordDecl() : 0) {
+        if (NSDecl->getIdentifier() == QR.getCorrectionAsIdentifierInfo())
+          continue;
+      }
+
+      TypoCorrection TC(QR);
+      TC.ClearCorrectionDecls();
+      TC.setCorrectionSpecifier(NSI.NameSpecifier);
+      TC.setQualifierDistance(NSI.EditDistance);
+      TC.setCallbackDistance(0); // Reset the callback distance
+
+      // If the current correction candidate and namespace combination are
+      // too far away from the original typo based on the normalized edit
+      // distance, then skip performing a qualified name lookup.
+      unsigned TmpED = TC.getEditDistance(true);
+      if (QR.getCorrectionAsIdentifierInfo() != Typo && TmpED &&
+          TypoLen / TmpED < 3)
+        continue;
+
+      Result.clear();
+      Result.setLookupName(QR.getCorrectionAsIdentifierInfo());
+      if (!SemaRef.LookupQualifiedName(Result, Ctx))
+        continue;
+
+      // Any corrections added below will be validated in subsequent
+      // iterations of the main while() loop over the Consumer's contents.
+      switch (Result.getResultKind()) {
+      case LookupResult::Found:
+      case LookupResult::FoundOverloaded: {
+        if (SS && SS->isValid()) {
+          std::string NewQualified = TC.getAsString(SemaRef.getLangOpts());
+          std::string OldQualified;
+          llvm::raw_string_ostream OldOStream(OldQualified);
+          SS->getScopeRep()->print(OldOStream, SemaRef.getPrintingPolicy());
+          OldOStream << Typo->getName();
+          // If correction candidate would be an identical written qualified
+          // identifer, then the existing CXXScopeSpec probably included a
+          // typedef that didn't get accounted for properly.
+          if (OldOStream.str() == NewQualified)
+            break;
+        }
+        for (LookupResult::iterator TRD = Result.begin(), TRDEnd = Result.end();
+             TRD != TRDEnd; ++TRD) {
+          if (SemaRef.CheckMemberAccess(TC.getCorrectionRange().getBegin(),
+                                        NSType ? NSType->getAsCXXRecordDecl()
+                                               : nullptr,
+                                        TRD.getPair()) == Sema::AR_accessible)
+            TC.addCorrectionDecl(*TRD);
+        }
+        if (TC.isResolved())
+          addCorrection(TC);
+        break;
+      }
+      case LookupResult::NotFound:
+      case LookupResult::NotFoundInCurrentInstantiation:
+      case LookupResult::Ambiguous:
+      case LookupResult::FoundUnresolvedValue:
+        break;
+      }
+    }
+  }
+  QualifiedResults.clear();
+}
+
+TypoCorrectionConsumer::NamespaceSpecifierSet::NamespaceSpecifierSet(
+    ASTContext &Context, DeclContext *CurContext, CXXScopeSpec *CurScopeSpec)
+    : Context(Context), CurContextChain(buildContextChain(CurContext)),
+      isSorted(false) {
+  if (NestedNameSpecifier *NNS =
+          CurScopeSpec ? CurScopeSpec->getScopeRep() : nullptr) {
+    llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
+    NNS->print(SpecifierOStream, Context.getPrintingPolicy());
+
+    getNestedNameSpecifierIdentifiers(NNS, CurNameSpecifierIdentifiers);
+  }
+  // Build the list of identifiers that would be used for an absolute
+  // (from the global context) NestedNameSpecifier referring to the current
+  // context.
+  for (DeclContextList::reverse_iterator C = CurContextChain.rbegin(),
+                                         CEnd = CurContextChain.rend();
+       C != CEnd; ++C) {
+    if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C))
+      CurContextIdentifiers.push_back(ND->getIdentifier());
+  }
+
+  // Add the global context as a NestedNameSpecifier
+  Distances.insert(1);
+  SpecifierInfo SI = {cast<DeclContext>(Context.getTranslationUnitDecl()),
+                      NestedNameSpecifier::GlobalSpecifier(Context), 1};
+  DistanceMap[1].push_back(SI);
+}
+
+auto TypoCorrectionConsumer::NamespaceSpecifierSet::buildContextChain(
+    DeclContext *Start) -> DeclContextList {
   assert(Start && "Building a context chain from a null context");
   DeclContextList Chain;
   for (DeclContext *DC = Start->getPrimaryContext(); DC != nullptr;
@@ -3541,7 +3781,7 @@
   return Chain;
 }
 
-void NamespaceSpecifierSet::SortNamespaces() {
+void TypoCorrectionConsumer::NamespaceSpecifierSet::sortNamespaces() {
   SmallVector<unsigned, 4> sortedDistances;
   sortedDistances.append(Distances.begin(), Distances.end());
 
@@ -3559,9 +3799,9 @@
   isSorted = true;
 }
 
-static unsigned BuildNestedNameSpecifier(ASTContext &Context,
-                                         DeclContextList &DeclChain,
-                                         NestedNameSpecifier *&NNS) {
+unsigned
+TypoCorrectionConsumer::NamespaceSpecifierSet::buildNestedNameSpecifier(
+    DeclContextList &DeclChain, NestedNameSpecifier *&NNS) {
   unsigned NumSpecifiers = 0;
   for (DeclContextList::reverse_iterator C = DeclChain.rbegin(),
                                       CEnd = DeclChain.rend();
@@ -3578,10 +3818,11 @@
   return NumSpecifiers;
 }
 
-void NamespaceSpecifierSet::AddNameSpecifier(DeclContext *Ctx) {
+void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier(
+    DeclContext *Ctx) {
   NestedNameSpecifier *NNS = nullptr;
   unsigned NumSpecifiers = 0;
-  DeclContextList NamespaceDeclChain(BuildContextChain(Ctx));
+  DeclContextList NamespaceDeclChain(buildContextChain(Ctx));
   DeclContextList FullNamespaceDeclChain(NamespaceDeclChain);
 
   // Eliminate common elements from the two DeclContext chains.
@@ -3593,14 +3834,14 @@
   }
 
   // Build the NestedNameSpecifier from what is left of the NamespaceDeclChain
-  NumSpecifiers = BuildNestedNameSpecifier(Context, NamespaceDeclChain, NNS);
+  NumSpecifiers = buildNestedNameSpecifier(NamespaceDeclChain, NNS);
 
   // Add an explicit leading '::' specifier if needed.
   if (NamespaceDeclChain.empty()) {
     // Rebuild the NestedNameSpecifier as a globally-qualified specifier.
     NNS = NestedNameSpecifier::GlobalSpecifier(Context);
     NumSpecifiers =
-        BuildNestedNameSpecifier(Context, FullNamespaceDeclChain, NNS);
+        buildNestedNameSpecifier(FullNamespaceDeclChain, NNS);
   } else if (NamedDecl *ND =
                  dyn_cast_or_null<NamedDecl>(NamespaceDeclChain.back())) {
     IdentifierInfo *Name = ND->getIdentifier();
@@ -3622,7 +3863,7 @@
       // Rebuild the NestedNameSpecifier as a globally-qualified specifier.
       NNS = NestedNameSpecifier::GlobalSpecifier(Context);
       NumSpecifiers =
-          BuildNestedNameSpecifier(Context, FullNamespaceDeclChain, NNS);
+          buildNestedNameSpecifier(FullNamespaceDeclChain, NNS);
     }
   }
 
@@ -3640,7 +3881,8 @@
 
   isSorted = false;
   Distances.insert(NumSpecifiers);
-  DistanceMap[NumSpecifiers].push_back(SpecifierInfo(Ctx, NNS, NumSpecifiers));
+  SpecifierInfo SI = {Ctx, NNS, NumSpecifiers};
+  DistanceMap[NumSpecifiers].push_back(SI);
 }
 
 /// \brief Perform name lookup for a possible result for typo correction.
@@ -3840,17 +4082,10 @@
   }
 }
 
-static bool isCandidateViable(CorrectionCandidateCallback &CCC,
-                              TypoCorrection &Candidate) {
-  Candidate.setCallbackDistance(CCC.RankCandidate(Candidate));
-  return Candidate.getEditDistance(false) != TypoCorrection::InvalidDistance;
-}
-
 /// \brief Check whether the declarations found for a typo correction are
 /// visible, and if none of them are, convert the correction to an 'import
 /// a module' correction.
-static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC,
-                                      DeclarationName TypoName) {
+static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) {
   if (TC.begin() == TC.end())
     return;
 
@@ -3980,8 +4215,6 @@
   if (getLangOpts().AltiVec && Typo->isStr("vector"))
     return TypoCorrection();
 
-  TypoCorrectionConsumer Consumer(*this, Typo);
-
   // If we're handling a missing symbol error, using modules, and the
   // special search all modules option is used, look for a missing import.
   if ((Mode == CTK_ErrorRecovery) &&  getLangOpts().Modules &&
@@ -3991,7 +4224,8 @@
                                            TypoName.getLocStart());
   }
 
-  NamespaceSpecifierSet Namespaces(Context, CurContext, SS);
+  TypoCorrectionConsumer Consumer(*this, TypoName, LookupKind, S, SS, CCC,
+                                  MemberContext, EnteringContext);
 
   // If a callback object considers an empty typo correction candidate to be
   // viable, assume it does not do any actual validation of the candidates.
@@ -4116,236 +4350,15 @@
         KnownNamespaces[ExternalKnownNamespaces[I]] = true;
     }
 
-    for (auto KNPair : KnownNamespaces)
-      Namespaces.AddNameSpecifier(KNPair.first);
-
-    bool SSIsTemplate = false;
-    if (NestedNameSpecifier *NNS =
-            (SS && SS->isValid()) ? SS->getScopeRep() : nullptr) {
-      if (const Type *T = NNS->getAsType())
-        SSIsTemplate = T->getTypeClass() == Type::TemplateSpecialization;
-    }
-    for (const auto *TI : Context.types()) {
-      if (CXXRecordDecl *CD = TI->getAsCXXRecordDecl()) {
-        CD = CD->getCanonicalDecl();
-        if (!CD->isDependentType() && !CD->isAnonymousStructOrUnion() &&
-            !CD->isUnion() && CD->getIdentifier() &&
-            (SSIsTemplate || !isa<ClassTemplateSpecializationDecl>(CD)) &&
-            (CD->isBeingDefined() || CD->isCompleteDefinition()))
-          Namespaces.AddNameSpecifier(CD);
-      }
-    }
+    Consumer.addNamespaces(KnownNamespaces);
   }
 
-  // Weed out any names that could not be found by name lookup or, if a
-  // CorrectionCandidateCallback object was provided, failed validation.
-  SmallVector<TypoCorrection, 16> QualifiedResults;
-  LookupResult TmpRes(*this, TypoName, LookupKind);
-  TmpRes.suppressDiagnostics();
-  while (!Consumer.empty()) {
-    TypoCorrectionConsumer::distance_iterator DI = Consumer.begin();
-    for (TypoCorrectionConsumer::result_iterator I = DI->second.begin(),
-                                              IEnd = DI->second.end();
-         I != IEnd; /* Increment in loop. */) {
-      // If we only want nested name specifier corrections, ignore potential
-      // corrections that have a different base identifier from the typo or
-      // which have a normalized edit distance longer than the typo itself.
-      if (AllowOnlyNNSChanges) {
-        TypoCorrection &TC = I->second.front();
-        if (TC.getCorrectionAsIdentifierInfo() != Typo ||
-            TC.getEditDistance(true) > TypoLen) {
-          TypoCorrectionConsumer::result_iterator Prev = I;
-          ++I;
-          DI->second.erase(Prev);
-          continue;
-        }
-      }
-
-      // If the item already has been looked up or is a keyword, keep it.
-      // If a validator callback object was given, drop the correction
-      // unless it passes validation.
-      bool Viable = false;
-      for (TypoResultList::iterator RI = I->second.begin();
-           RI != I->second.end(); /* Increment in loop. */) {
-        TypoResultList::iterator Prev = RI;
-        ++RI;
-        if (Prev->isResolved()) {
-          if (!isCandidateViable(CCC, *Prev))
-            RI = I->second.erase(Prev);
-          else
-            Viable = true;
-        }
-      }
-      if (Viable || I->second.empty()) {
-        TypoCorrectionConsumer::result_iterator Prev = I;
-        ++I;
-        if (!Viable)
-          DI->second.erase(Prev);
-        continue;
-      }
-      assert(I->second.size() == 1 && "Expected a single unresolved candidate");
-
-      // Perform name lookup on this name.
-      TypoCorrection &Candidate = I->second.front();
-      IdentifierInfo *Name = Candidate.getCorrectionAsIdentifierInfo();
-      DeclContext *TempMemberContext = MemberContext;
-      CXXScopeSpec *TempSS = SS;
-retry_lookup:
-      LookupPotentialTypoResult(*this, TmpRes, Name, S, TempSS,
-                                TempMemberContext, EnteringContext,
-                                CCC.IsObjCIvarLookup,
-                                Name == TypoName.getName() &&
-                                  !Candidate.WillReplaceSpecifier());
-
-      switch (TmpRes.getResultKind()) {
-      case LookupResult::NotFound:
-      case LookupResult::NotFoundInCurrentInstantiation:
-      case LookupResult::FoundUnresolvedValue:
-        if (TempSS) {
-          // Immediately retry the lookup without the given CXXScopeSpec
-          TempSS = nullptr;
-          Candidate.WillReplaceSpecifier(true);
-          goto retry_lookup;
-        }
-        if (TempMemberContext) {
-          if (SS && !TempSS)
-            TempSS = SS;
-          TempMemberContext = nullptr;
-          goto retry_lookup;
-        }
-        QualifiedResults.push_back(Candidate);
-        // We didn't find this name in our scope, or didn't like what we found;
-        // ignore it.
-        {
-          TypoCorrectionConsumer::result_iterator Next = I;
-          ++Next;
-          DI->second.erase(I);
-          I = Next;
-        }
-        break;
-
-      case LookupResult::Ambiguous:
-        // We don't deal with ambiguities.
-        return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
-
-      case LookupResult::FoundOverloaded: {
-        TypoCorrectionConsumer::result_iterator Prev = I;
-        // Store all of the Decls for overloaded symbols
-        for (auto *TRD : TmpRes)
-          Candidate.addCorrectionDecl(TRD);
-        ++I;
-        if (!isCandidateViable(CCC, Candidate)) {
-          QualifiedResults.push_back(Candidate);
-          DI->second.erase(Prev);
-        }
-        break;
-      }
-
-      case LookupResult::Found: {
-        TypoCorrectionConsumer::result_iterator Prev = I;
-        Candidate.setCorrectionDecl(TmpRes.getAsSingle<NamedDecl>());
-        ++I;
-        if (!isCandidateViable(CCC, Candidate)) {
-          QualifiedResults.push_back(Candidate);
-          DI->second.erase(Prev);
-        }
-        break;
-      }
-
-      }
-    }
-
-    if (DI->second.empty())
-      Consumer.erase(DI);
-    else if (!getLangOpts().CPlusPlus || QualifiedResults.empty() || !DI->first)
-      // If there are results in the closest possible bucket, stop
-      break;
-
-    // Only perform the qualified lookups for C++
-    if (SearchNamespaces) {
-      TmpRes.suppressDiagnostics();
-      for (auto QR : QualifiedResults) {
-        for (auto NSI : Namespaces) {
-          DeclContext *Ctx = NSI.DeclCtx;
-          const Type *NSType = NSI.NameSpecifier->getAsType();
-
-          // If the current NestedNameSpecifier refers to a class and the
-          // current correction candidate is the name of that class, then skip
-          // it as it is unlikely a qualified version of the class' constructor
-          // is an appropriate correction.
-          if (CXXRecordDecl *NSDecl =
-                  NSType ? NSType->getAsCXXRecordDecl() : nullptr) {
-            if (NSDecl->getIdentifier() == QR.getCorrectionAsIdentifierInfo())
-              continue;
-          }
-
-          TypoCorrection TC(QR);
-          TC.ClearCorrectionDecls();
-          TC.setCorrectionSpecifier(NSI.NameSpecifier);
-          TC.setQualifierDistance(NSI.EditDistance);
-          TC.setCallbackDistance(0); // Reset the callback distance
-
-          // If the current correction candidate and namespace combination are
-          // too far away from the original typo based on the normalized edit
-          // distance, then skip performing a qualified name lookup.
-          unsigned TmpED = TC.getEditDistance(true);
-          if (QR.getCorrectionAsIdentifierInfo() != Typo &&
-              TmpED && TypoLen / TmpED < 3)
-            continue;
-
-          TmpRes.clear();
-          TmpRes.setLookupName(QR.getCorrectionAsIdentifierInfo());
-          if (!LookupQualifiedName(TmpRes, Ctx)) continue;
-
-          // Any corrections added below will be validated in subsequent
-          // iterations of the main while() loop over the Consumer's contents.
-          switch (TmpRes.getResultKind()) {
-          case LookupResult::Found:
-          case LookupResult::FoundOverloaded: {
-            if (SS && SS->isValid()) {
-              std::string NewQualified = TC.getAsString(getLangOpts());
-              std::string OldQualified;
-              llvm::raw_string_ostream OldOStream(OldQualified);
-              SS->getScopeRep()->print(OldOStream, getPrintingPolicy());
-              OldOStream << TypoName;
-              // If correction candidate would be an identical written qualified
-              // identifer, then the existing CXXScopeSpec probably included a
-              // typedef that didn't get accounted for properly.
-              if (OldOStream.str() == NewQualified)
-                break;
-            }
-            for (LookupResult::iterator TRD = TmpRes.begin(),
-                                     TRDEnd = TmpRes.end();
-                 TRD != TRDEnd; ++TRD) {
-              if (CheckMemberAccess(TC.getCorrectionRange().getBegin(),
-                                    NSType ? NSType->getAsCXXRecordDecl()
-                                           : nullptr,
-                                    TRD.getPair()) == AR_accessible)
-                TC.addCorrectionDecl(*TRD);
-            }
-            if (TC.isResolved())
-              Consumer.addCorrection(TC);
-            break;
-          }
-          case LookupResult::NotFound:
-          case LookupResult::NotFoundInCurrentInstantiation:
-          case LookupResult::Ambiguous:
-          case LookupResult::FoundUnresolvedValue:
-            break;
-          }
-        }
-      }
-    }
-
-    QualifiedResults.clear();
-  }
-
-  // No corrections remain...
-  if (Consumer.empty())
+  TypoCorrection BestTC = Consumer.getNextCorrection();
+  TypoCorrection SecondBestTC = Consumer.getNextCorrection();
+  if (!BestTC)
     return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
 
-  TypoResultsMap &BestResults = Consumer.getBestResults();
-  ED = Consumer.getBestEditDistance(true);
+  ED = BestTC.getEditDistance();
 
   if (!AllowOnlyNNSChanges && ED > 0 && TypoLen / ED < 3) {
     // If this was an unqualified lookup and we believe the callback
@@ -4356,11 +4369,9 @@
   }
 
   // If only a single name remains, return that result.
-  if (BestResults.size() == 1) {
-    const TypoResultList &CorrectionList = BestResults.begin()->second;
-    const TypoCorrection &Result = CorrectionList.front();
-    if (CorrectionList.size() != 1)
-      return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
+  if (!SecondBestTC ||
+      SecondBestTC.getEditDistance(false) > BestTC.getEditDistance(false)) {
+    const TypoCorrection &Result = BestTC;
 
     // Don't correct to a keyword that's the same as the typo; the keyword
     // wasn't actually in scope.
@@ -4373,39 +4384,42 @@
 
     TypoCorrection TC = Result;
     TC.setCorrectionRange(SS, TypoName);
-    checkCorrectionVisibility(*this, TC, TypoName.getName());
+    checkCorrectionVisibility(*this, TC);
     return TC;
   }
-  else if (BestResults.size() > 1
-           // Ugly hack equivalent to CTC == CTC_ObjCMessageReceiver;
-           // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for
-           // some instances of CTC_Unknown, while WantRemainingKeywords is true
-           // for CTC_Unknown but not for CTC_ObjCMessageReceiver.
-           && CCC.WantObjCSuper && !CCC.WantRemainingKeywords
-           && BestResults["super"].front().isKeyword()) {
+  // Ugly hack equivalent to CTC == CTC_ObjCMessageReceiver;
+  // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for
+  // some instances of CTC_Unknown, while WantRemainingKeywords is true
+  // for CTC_Unknown but not for CTC_ObjCMessageReceiver.
+  else if (SecondBestTC && CCC.WantObjCSuper && !CCC.WantRemainingKeywords) {
     // Prefer 'super' when we're completing in a message-receiver
     // context.
 
+    if (BestTC.getCorrection().getAsString() != "super") {
+      if (SecondBestTC.getCorrection().getAsString() == "super")
+        BestTC = SecondBestTC;
+      else if (Consumer["super"].front().isKeyword())
+        BestTC = Consumer["super"].front();
+    }
     // Don't correct to a keyword that's the same as the typo; the keyword
     // wasn't actually in scope.
-    if (ED == 0)
+    if (BestTC.getEditDistance() == 0 ||
+        BestTC.getCorrection().getAsString() != "super")
       return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
 
     // Record the correction for unqualified lookup.
     if (IsUnqualifiedLookup)
-      UnqualifiedTyposCorrected[Typo] = BestResults["super"].front();
+      UnqualifiedTyposCorrected[Typo] = BestTC;
 
-    TypoCorrection TC = BestResults["super"].front();
-    TC.setCorrectionRange(SS, TypoName);
-    return TC;
+    BestTC.setCorrectionRange(SS, TypoName);
+    return BestTC;
   }
 
-  // If this was an unqualified lookup and we believe the callback object did
-  // not filter out possible corrections, note that no correction was found.
-  if (IsUnqualifiedLookup && !ValidatingCallback)
-    (void)UnqualifiedTyposCorrected[Typo];
-
-  return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
+  // Record the failure's location if needed and return an empty correction. If
+  // this was an unqualified lookup and we believe the callback object did not
+  // filter out possible corrections, also cache the failure for the typo.
+  return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure,
+                          IsUnqualifiedLookup && !ValidatingCallback);
 }
 
 void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) {
@@ -4440,14 +4454,27 @@
     return WantTypeSpecifiers || WantExpressionKeywords || WantCXXNamedCasts ||
            WantRemainingKeywords || WantObjCSuper;
 
-  for (TypoCorrection::const_decl_iterator CDecl = candidate.begin(),
-                                           CDeclEnd = candidate.end();
-       CDecl != CDeclEnd; ++CDecl) {
-    if (!isa<TypeDecl>(*CDecl))
-      return true;
+  bool HasNonType = false;
+  bool HasStaticMethod = false;
+  bool HasNonStaticMethod = false;
+  for (Decl *D : candidate) {
+    if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
+      D = FTD->getTemplatedDecl();
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+      if (Method->isStatic())
+        HasStaticMethod = true;
+      else
+        HasNonStaticMethod = true;
+    }
+    if (!isa<TypeDecl>(D))
+      HasNonType = true;
   }
 
-  return WantTypeSpecifiers;
+  if (IsAddressOfOperand && HasNonStaticMethod && !HasStaticMethod &&
+      !candidate.getCorrectionSpecifier())
+    return false;
+
+  return WantTypeSpecifiers || HasNonType;
 }
 
 FunctionCallFilterCCC::FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index bc98299..8eb806b 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -1156,9 +1156,9 @@
           InitializedEntity::InitializeResult(PropertyDiagLoc,
                                               getterMethod->getReturnType(),
                                               /*NRVO=*/false),
-          PropertyDiagLoc, Owned(IvarRefExpr));
+          PropertyDiagLoc, IvarRefExpr);
       if (!Res.isInvalid()) {
-        Expr *ResExpr = Res.takeAs<Expr>();
+        Expr *ResExpr = Res.getAs<Expr>();
         if (ResExpr)
           ResExpr = MaybeCreateExprWithCleanups(ResExpr);
         PIDecl->setGetterCXXConstructor(ResExpr);
@@ -1212,7 +1212,7 @@
                                   BO_Assign, lhs, rhs);
       if (property->getPropertyAttributes() & 
           ObjCPropertyDecl::OBJC_PR_atomic) {
-        Expr *callExpr = Res.takeAs<Expr>();
+        Expr *callExpr = Res.getAs<Expr>();
         if (const CXXOperatorCallExpr *CXXCE = 
               dyn_cast_or_null<CXXOperatorCallExpr>(callExpr))
           if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
@@ -1225,7 +1225,7 @@
                      diag::note_callee_decl) << FuncDecl;
               }
       }
-      PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
+      PIDecl->setSetterCXXAssignment(Res.getAs<Expr>());
     }
   }
   
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 603dd56..a7ad809 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -40,6 +40,26 @@
   DSA_shared = 1 << 1  /// \brief Default data sharing attribute 'shared'.
 };
 
+template <class T> struct MatchesAny {
+  explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {}
+  bool operator()(T Kind) {
+    for (auto KindEl : Arr)
+      if (KindEl == Kind)
+        return true;
+    return false;
+  }
+
+private:
+  ArrayRef<T> Arr;
+};
+struct MatchesAlways {
+  MatchesAlways() {}
+  template <class T> bool operator()(T) { return true; }
+};
+
+typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause;
+typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective;
+
 /// \brief Stack for tracking declarations used in OpenMP directives and
 /// clauses and their data-sharing attributes.
 class DSAStackTy {
@@ -48,7 +68,10 @@
     OpenMPDirectiveKind DKind;
     OpenMPClauseKind CKind;
     DeclRefExpr *RefExpr;
-    DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr) {}
+    SourceLocation ImplicitDSALoc;
+    DSAVarData()
+        : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr),
+          ImplicitDSALoc() {}
   };
 
 private:
@@ -57,27 +80,33 @@
     DeclRefExpr *RefExpr;
   };
   typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
+  typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
 
   struct SharingMapTy {
     DeclSAMapTy SharingMap;
+    AlignedMapTy AlignedMap;
     DefaultDataSharingAttributes DefaultAttr;
+    SourceLocation DefaultAttrLoc;
     OpenMPDirectiveKind Directive;
     DeclarationNameInfo DirectiveName;
     Scope *CurScope;
+    SourceLocation ConstructLoc;
     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
-                 Scope *CurScope)
-        : SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind),
-          DirectiveName(std::move(Name)), CurScope(CurScope) {}
+                 Scope *CurScope, SourceLocation Loc)
+        : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
+          Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
+          ConstructLoc(Loc) {}
     SharingMapTy()
-        : SharingMap(), DefaultAttr(DSA_unspecified), Directive(OMPD_unknown),
-          DirectiveName(), CurScope(nullptr) {}
+        : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
+          Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
+          ConstructLoc() {}
   };
 
   typedef SmallVector<SharingMapTy, 64> StackTy;
 
   /// \brief Stack of used declaration and their data-sharing attributes.
   StackTy Stack;
-  Sema &Actions;
+  Sema &SemaRef;
 
   typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
 
@@ -87,11 +116,12 @@
   bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
 
 public:
-  explicit DSAStackTy(Sema &S) : Stack(1), Actions(S) {}
+  explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {}
 
   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
-            Scope *CurScope) {
-    Stack.push_back(SharingMapTy(DKind, DirName, CurScope));
+            Scope *CurScope, SourceLocation Loc) {
+    Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
+    Stack.back().DefaultAttrLoc = Loc;
   }
 
   void pop() {
@@ -99,6 +129,11 @@
     Stack.pop_back();
   }
 
+  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
+  /// add it and return NULL; otherwise return previous occurrence's expression
+  /// for diagnostics.
+  DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE);
+
   /// \brief Adds explicit data sharing attribute to the specified declaration.
   void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
 
@@ -107,46 +142,69 @@
   DSAVarData getTopDSA(VarDecl *D);
   /// \brief Returns data-sharing attributes for the specified declaration.
   DSAVarData getImplicitDSA(VarDecl *D);
-  /// \brief Checks if the specified variables has \a CKind data-sharing
-  /// attribute in \a DKind directive.
-  DSAVarData hasDSA(VarDecl *D, OpenMPClauseKind CKind,
-                    OpenMPDirectiveKind DKind = OMPD_unknown);
+  /// \brief Checks if the specified variables has data-sharing attributes which
+  /// match specified \a CPred predicate in any directive which matches \a DPred
+  /// predicate.
+  template <class ClausesPredicate, class DirectivesPredicate>
+  DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred,
+                    DirectivesPredicate DPred);
+  /// \brief Checks if the specified variables has data-sharing attributes which
+  /// match specified \a CPred predicate in any innermost directive which
+  /// matches \a DPred predicate.
+  template <class ClausesPredicate, class DirectivesPredicate>
+  DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
+                             DirectivesPredicate DPred);
 
   /// \brief Returns currently analyzed directive.
   OpenMPDirectiveKind getCurrentDirective() const {
     return Stack.back().Directive;
   }
+  /// \brief Returns parent directive.
+  OpenMPDirectiveKind getParentDirective() const {
+    if (Stack.size() > 2)
+      return Stack[Stack.size() - 2].Directive;
+    return OMPD_unknown;
+  }
 
   /// \brief Set default data sharing attribute to none.
-  void setDefaultDSANone() { Stack.back().DefaultAttr = DSA_none; }
+  void setDefaultDSANone(SourceLocation Loc) {
+    Stack.back().DefaultAttr = DSA_none;
+    Stack.back().DefaultAttrLoc = Loc;
+  }
   /// \brief Set default data sharing attribute to shared.
-  void setDefaultDSAShared() { Stack.back().DefaultAttr = DSA_shared; }
+  void setDefaultDSAShared(SourceLocation Loc) {
+    Stack.back().DefaultAttr = DSA_shared;
+    Stack.back().DefaultAttrLoc = Loc;
+  }
 
   DefaultDataSharingAttributes getDefaultDSA() const {
     return Stack.back().DefaultAttr;
   }
+  SourceLocation getDefaultDSALocation() const {
+    return Stack.back().DefaultAttrLoc;
+  }
 
-  /// \brief Checks if the spewcified variable is threadprivate.
+  /// \brief Checks if the specified variable is a threadprivate.
   bool isThreadPrivate(VarDecl *D) {
     DSAVarData DVar = getTopDSA(D);
-    return (DVar.CKind == OMPC_threadprivate || DVar.CKind == OMPC_copyin);
+    return isOpenMPThreadPrivate(DVar.CKind);
   }
 
   Scope *getCurScope() const { return Stack.back().CurScope; }
   Scope *getCurScope() { return Stack.back().CurScope; }
+  SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
 };
 } // namespace
 
 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
                                           VarDecl *D) {
   DSAVarData DVar;
-  if (Iter == Stack.rend() - 1) {
+  if (Iter == std::prev(Stack.rend())) {
     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
     // in a region but not in construct]
     //  File-scope or namespace-scope variables referenced in called routines
     //  in the region are shared unless they appear in a threadprivate
     //  directive.
-    // TODO
     if (!D->isFunctionOrMethodVarDecl())
       DVar.CKind = OMPC_shared;
 
@@ -165,12 +223,10 @@
   // in a Construct, C/C++, predetermined, p.1]
   // Variables with automatic storage duration that are declared in a scope
   // inside the construct are private.
-  if (DVar.DKind != OMPD_parallel) {
-    if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
-        (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
-      DVar.CKind = OMPC_private;
-      return DVar;
-    }
+  if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
+      (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
+    DVar.CKind = OMPC_private;
+    return DVar;
   }
 
   // Explicitly specified attributes and local variables with predetermined
@@ -188,6 +244,7 @@
   switch (Iter->DefaultAttr) {
   case DSA_shared:
     DVar.CKind = OMPC_shared;
+    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
     return DVar;
   case DSA_none:
     return DVar;
@@ -196,7 +253,8 @@
     // in a Construct, implicitly determined, p.2]
     //  In a parallel construct, if no default clause is present, these
     //  variables are shared.
-    if (DVar.DKind == OMPD_parallel) {
+    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
+    if (isOpenMPParallelDirective(DVar.DKind)) {
       DVar.CKind = OMPC_shared;
       return DVar;
     }
@@ -206,7 +264,6 @@
     //  In a task construct, if no default clause is present, a variable that in
     //  the enclosing context is determined to be shared by all implicit tasks
     //  bound to the current team is shared.
-    // TODO
     if (DVar.DKind == OMPD_task) {
       DSAVarData DVarTemp;
       for (StackTy::reverse_iterator I = std::next(Iter),
@@ -225,7 +282,7 @@
           DVar.CKind = OMPC_firstprivate;
           return DVar;
         }
-        if (I->Directive == OMPD_parallel)
+        if (isOpenMPParallelDirective(I->Directive))
           break;
       }
       DVar.DKind = OMPD_task;
@@ -242,6 +299,20 @@
   return getDSA(std::next(Iter), D);
 }
 
+DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) {
+  assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
+  auto It = Stack.back().AlignedMap.find(D);
+  if (It == Stack.back().AlignedMap.end()) {
+    assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
+    Stack.back().AlignedMap[D] = NewDE;
+    return nullptr;
+  } else {
+    assert(It->second && "Unexpected nullptr expr in the aligned map");
+    return It->second;
+  }
+  return nullptr;
+}
+
 void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
   if (A == OMPC_threadprivate) {
     Stack[0].SharingMap[D].Attributes = A;
@@ -255,9 +326,9 @@
 
 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
   if (Stack.size() > 2) {
-    reverse_iterator I = Iter, E = Stack.rend() - 1;
+    reverse_iterator I = Iter, E = std::prev(Stack.rend());
     Scope *TopScope = nullptr;
-    while (I != E && I->Directive != OMPD_parallel) {
+    while (I != E && !isOpenMPParallelDirective(I->Directive)) {
       ++I;
     }
     if (I == E)
@@ -293,7 +364,7 @@
   // Variables with automatic storage duration that are declared in a scope
   // inside the construct are private.
   OpenMPDirectiveKind Kind = getCurrentDirective();
-  if (Kind != OMPD_parallel) {
+  if (!isOpenMPParallelDirective(Kind)) {
     if (isOpenMPLocal(D, std::next(Stack.rbegin())) && D->isLocalVarDecl() &&
         (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
       DVar.CKind = OMPC_private;
@@ -303,12 +374,12 @@
 
   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
   // in a Construct, C/C++, predetermined, p.4]
-  //  Static data memebers are shared.
+  //  Static data members are shared.
   if (D->isStaticDataMember()) {
     // Variables with const-qualified type having no mutable member may be
-    // listed
-    // in a firstprivate clause, even if they are static data members.
-    DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
+    // listed in a firstprivate clause, even if they are static data members.
+    DSAVarData DVarTemp =
+        hasDSA(D, MatchesAnyClause(OMPC_firstprivate), MatchesAlways());
     if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
       return DVar;
 
@@ -317,7 +388,7 @@
   }
 
   QualType Type = D->getType().getNonReferenceType().getCanonicalType();
-  bool IsConstant = Type.isConstant(Actions.getASTContext());
+  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
   while (Type->isArrayType()) {
     QualType ElemType = cast<ArrayType>(Type.getTypePtr())->getElementType();
     Type = ElemType.getNonReferenceType().getCanonicalType();
@@ -327,12 +398,13 @@
   //  Variables with const qualified type having no mutable member are
   //  shared.
   CXXRecordDecl *RD =
-      Actions.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+      SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
   if (IsConstant &&
-      !(Actions.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
+      !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
     // Variables with const-qualified type having no mutable member may be
     // listed in a firstprivate clause, even if they are static data members.
-    DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
+    DSAVarData DVarTemp =
+        hasDSA(D, MatchesAnyClause(OMPC_firstprivate), MatchesAlways());
     if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
       return DVar;
 
@@ -363,20 +435,36 @@
   return getDSA(std::next(Stack.rbegin()), D);
 }
 
-DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, OpenMPClauseKind CKind,
-                                          OpenMPDirectiveKind DKind) {
+template <class ClausesPredicate, class DirectivesPredicate>
+DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred,
+                                          DirectivesPredicate DPred) {
   for (StackTy::reverse_iterator I = std::next(Stack.rbegin()),
                                  E = std::prev(Stack.rend());
        I != E; ++I) {
-    if (DKind != OMPD_unknown && DKind != I->Directive)
+    if (!DPred(I->Directive))
       continue;
     DSAVarData DVar = getDSA(I, D);
-    if (DVar.CKind == CKind)
+    if (CPred(DVar.CKind))
       return DVar;
   }
   return DSAVarData();
 }
 
+template <class ClausesPredicate, class DirectivesPredicate>
+DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(VarDecl *D,
+                                                   ClausesPredicate CPred,
+                                                   DirectivesPredicate DPred) {
+  for (auto I = Stack.rbegin(), EE = std::prev(Stack.rend()); I != EE; ++I) {
+    if (!DPred(I->Directive))
+      continue;
+    DSAVarData DVar = getDSA(I, D);
+    if (CPred(DVar.CKind))
+      return DVar;
+    return DSAVarData();
+  }
+  return DSAVarData();
+}
+
 void Sema::InitDataSharingAttributesStack() {
   VarDataSharingAttributesStack = new DSAStackTy(*this);
 }
@@ -387,12 +475,62 @@
 
 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
                                const DeclarationNameInfo &DirName,
-                               Scope *CurScope) {
-  DSAStack->push(DKind, DirName, CurScope);
+                               Scope *CurScope, SourceLocation Loc) {
+  DSAStack->push(DKind, DirName, CurScope, Loc);
   PushExpressionEvaluationContext(PotentiallyEvaluated);
 }
 
 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
+  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
+  //  A variable of class type (or array thereof) that appears in a lastprivate
+  //  clause requires an accessible, unambiguous default constructor for the
+  //  class type, unless the list item is also specified in a firstprivate
+  //  clause.
+  if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
+    for (auto C : D->clauses()) {
+      if (auto Clause = dyn_cast<OMPLastprivateClause>(C)) {
+        for (auto VarRef : Clause->varlists()) {
+          if (VarRef->isValueDependent() || VarRef->isTypeDependent())
+            continue;
+          auto VD = cast<VarDecl>(cast<DeclRefExpr>(VarRef)->getDecl());
+          auto DVar = DSAStack->getTopDSA(VD);
+          if (DVar.CKind == OMPC_lastprivate) {
+            SourceLocation ELoc = VarRef->getExprLoc();
+            auto Type = VarRef->getType();
+            if (Type->isArrayType())
+              Type = QualType(Type->getArrayElementTypeNoTypeQual(), 0);
+            CXXRecordDecl *RD =
+                getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+            // FIXME This code must be replaced by actual constructing of the
+            // lastprivate variable.
+            if (RD) {
+              CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
+              PartialDiagnostic PD =
+                  PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+              if (!CD ||
+                  CheckConstructorAccess(
+                      ELoc, CD, InitializedEntity::InitializeTemporary(Type),
+                      CD->getAccess(), PD) == AR_inaccessible ||
+                  CD->isDeleted()) {
+                Diag(ELoc, diag::err_omp_required_method)
+                    << getOpenMPClauseName(OMPC_lastprivate) << 0;
+                bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                              VarDecl::DeclarationOnly;
+                Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl
+                                               : diag::note_defined_here)
+                    << VD;
+                Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+                continue;
+              }
+              MarkFunctionReferenced(ELoc, CD);
+              DiagnoseUseOfDecl(CD, ELoc);
+            }
+          }
+        }
+      }
+    }
+  }
+
   DSAStack->pop();
   DiscardCleanupsInEvaluationContext();
   PopExpressionEvaluationContext();
@@ -402,16 +540,16 @@
 
 class VarDeclFilterCCC : public CorrectionCandidateCallback {
 private:
-  Sema &Actions;
+  Sema &SemaRef;
 
 public:
-  VarDeclFilterCCC(Sema &S) : Actions(S) {}
+  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
   bool ValidateCandidate(const TypoCorrection &Candidate) override {
     NamedDecl *ND = Candidate.getCorrectionDecl();
     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
       return VD->hasGlobalStorage() &&
-             Actions.isDeclInScope(ND, Actions.getCurLexicalContext(),
-                                   Actions.getCurScope());
+             SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
+                                   SemaRef.getCurScope());
     }
     return false;
   }
@@ -553,6 +691,35 @@
   return DeclGroupPtrTy();
 }
 
+namespace {
+class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
+  Sema &SemaRef;
+
+public:
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    if (auto VD = dyn_cast<VarDecl>(E->getDecl())) {
+      if (VD->hasLocalStorage()) {
+        SemaRef.Diag(E->getLocStart(),
+                     diag::err_omp_local_var_in_threadprivate_init)
+            << E->getSourceRange();
+        SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
+            << VD << VD->getSourceRange();
+        return true;
+      }
+    }
+    return false;
+  }
+  bool VisitStmt(const Stmt *S) {
+    for (auto Child : S->children()) {
+      if (Child && Visit(Child))
+        return true;
+    }
+    return false;
+  }
+  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
+};
+} // namespace
+
 OMPThreadPrivateDecl *
 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
   SmallVector<Expr *, 8> Vars;
@@ -592,6 +759,14 @@
       continue;
     }
 
+    // Check if initial value of threadprivate variable reference variable with
+    // local storage (it is not supported by runtime).
+    if (auto Init = VD->getAnyInitializer()) {
+      LocalVarRefChecker Checker(*this);
+      if (Checker.Visit(Init))
+        continue;
+    }
+
     Vars.push_back(RefExpr);
     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
   }
@@ -604,13 +779,63 @@
   return D;
 }
 
+static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
+                              const VarDecl *VD, DSAStackTy::DSAVarData DVar,
+                              bool IsLoopIterVar = false) {
+  if (DVar.RefExpr) {
+    SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
+        << getOpenMPClauseName(DVar.CKind);
+    return;
+  }
+  enum {
+    PDSA_StaticMemberShared,
+    PDSA_StaticLocalVarShared,
+    PDSA_LoopIterVarPrivate,
+    PDSA_LoopIterVarLinear,
+    PDSA_LoopIterVarLastprivate,
+    PDSA_ConstVarShared,
+    PDSA_GlobalVarShared,
+    PDSA_LocalVarPrivate,
+    PDSA_Implicit
+  } Reason = PDSA_Implicit;
+  bool ReportHint = false;
+  if (IsLoopIterVar) {
+    if (DVar.CKind == OMPC_private)
+      Reason = PDSA_LoopIterVarPrivate;
+    else if (DVar.CKind == OMPC_lastprivate)
+      Reason = PDSA_LoopIterVarLastprivate;
+    else
+      Reason = PDSA_LoopIterVarLinear;
+  } else if (VD->isStaticLocal())
+    Reason = PDSA_StaticLocalVarShared;
+  else if (VD->isStaticDataMember())
+    Reason = PDSA_StaticMemberShared;
+  else if (VD->isFileVarDecl())
+    Reason = PDSA_GlobalVarShared;
+  else if (VD->getType().isConstant(SemaRef.getASTContext()))
+    Reason = PDSA_ConstVarShared;
+  else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
+    ReportHint = true;
+    Reason = PDSA_LocalVarPrivate;
+  }
+  if (Reason != PDSA_Implicit) {
+    SemaRef.Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
+        << Reason << ReportHint
+        << getOpenMPDirectiveName(Stack->getCurrentDirective());
+  } else if (DVar.ImplicitDSALoc.isValid()) {
+    SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
+        << getOpenMPClauseName(DVar.CKind);
+  }
+}
+
 namespace {
 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
   DSAStackTy *Stack;
-  Sema &Actions;
+  Sema &SemaRef;
   bool ErrorFound;
   CapturedStmt *CS;
   llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
+  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
 
 public:
   void VisitDeclRefExpr(DeclRefExpr *E) {
@@ -634,9 +859,9 @@
       // attribute, must have its data-sharing attribute explicitly determined
       // by being listed in a data-sharing attribute clause.
       if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
-          (DKind == OMPD_parallel || DKind == OMPD_task)) {
-        ErrorFound = true;
-        Actions.Diag(ELoc, diag::err_omp_no_dsa_for_variable) << VD;
+          (isOpenMPParallelDirective(DKind) || DKind == OMPD_task) &&
+          VarsWithInheritedDSA.count(VD) == 0) {
+        VarsWithInheritedDSA[VD] = E;
         return;
       }
 
@@ -644,7 +869,14 @@
       //  A list item that appears in a reduction clause of the innermost
       //  enclosing worksharing or parallel construct may not be accessed in an
       //  explicit task.
-      // TODO:
+      DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
+                                    MatchesAlways());
+      if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
+        ErrorFound = true;
+        SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
+        ReportOriginalDSA(SemaRef, Stack, VD, DVar);
+        return;
+      }
 
       // Define implicit data-sharing attributes for task.
       DVar = Stack->getImplicitDSA(VD);
@@ -669,31 +901,87 @@
 
   bool isErrorFound() { return ErrorFound; }
   ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
+  llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
+    return VarsWithInheritedDSA;
+  }
 
-  DSAAttrChecker(DSAStackTy *S, Sema &Actions, CapturedStmt *CS)
-      : Stack(S), Actions(Actions), ErrorFound(false), CS(CS) {}
+  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
+      : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
 };
 } // namespace
 
-void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, SourceLocation Loc,
-                                  Scope *CurScope) {
+void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
   switch (DKind) {
   case OMPD_parallel: {
     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
     QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
-    Sema::CapturedParamNameType Params[3] = {
-      std::make_pair(".global_tid.", KmpInt32PtrTy),
-      std::make_pair(".bound_tid.", KmpInt32PtrTy),
-      std::make_pair(StringRef(), QualType()) // __context with shared vars
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(".global_tid.", KmpInt32PtrTy),
+        std::make_pair(".bound_tid.", KmpInt32PtrTy),
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
     };
-    ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
     break;
   }
   case OMPD_simd: {
-    Sema::CapturedParamNameType Params[1] = {
-      std::make_pair(StringRef(), QualType()) // __context with shared vars
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
     };
-    ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_for: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_sections: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_section: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_single: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_parallel_for: {
+    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
+    QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(".global_tid.", KmpInt32PtrTy),
+        std::make_pair(".bound_tid.", KmpInt32PtrTy),
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_parallel_sections: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
     break;
   }
   case OMPD_threadprivate:
@@ -704,6 +992,131 @@
   }
 }
 
+bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
+                           OpenMPDirectiveKind CurrentRegion,
+                           SourceLocation StartLoc) {
+  // Allowed nesting of constructs
+  // +------------------+-----------------+------------------------------------+
+  // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)|
+  // +------------------+-----------------+------------------------------------+
+  // | parallel         | parallel        | *                                  |
+  // | parallel         | for             | *                                  |
+  // | parallel         | simd            | *                                  |
+  // | parallel         | sections        | *                                  |
+  // | parallel         | section         | +                                  | 
+  // | parallel         | single          | *                                  |
+  // | parallel         | parallel for    | *                                  |
+  // | parallel         |parallel sections| *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | for              | parallel        | *                                  |
+  // | for              | for             | +                                  |
+  // | for              | simd            | *                                  |
+  // | for              | sections        | +                                  |
+  // | for              | section         | +                                  |
+  // | for              | single          | +                                  |
+  // | for              | parallel for    | *                                  |
+  // | for              |parallel sections| *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | simd             | parallel        |                                    |
+  // | simd             | for             |                                    |
+  // | simd             | simd            |                                    |
+  // | simd             | sections        |                                    |
+  // | simd             | section         |                                    |
+  // | simd             | single          |                                    |
+  // | simd             | parallel for    |                                    |
+  // | simd             |parallel sections|                                    |
+  // +------------------+-----------------+------------------------------------+
+  // | sections         | parallel        | *                                  |
+  // | sections         | for             | +                                  |
+  // | sections         | simd            | *                                  |
+  // | sections         | sections        | +                                  |
+  // | sections         | section         | *                                  |
+  // | sections         | single          | +                                  |
+  // | sections         | parallel for    | *                                  |
+  // | sections         |parallel sections| *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | section          | parallel        | *                                  |
+  // | section          | for             | +                                  |
+  // | section          | simd            | *                                  |
+  // | section          | sections        | +                                  |
+  // | section          | section         | +                                  |
+  // | section          | single          | +                                  |
+  // | section          | parallel for    | *                                  |
+  // | section          |parallel sections| *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | single           | parallel        | *                                  |
+  // | single           | for             | +                                  |
+  // | single           | simd            | *                                  |
+  // | single           | sections        | +                                  |
+  // | single           | section         | +                                  |
+  // | single           | single          | +                                  |
+  // | single           | parallel for    | *                                  |
+  // | single           |parallel sections| *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | parallel for     | parallel        | *                                  |
+  // | parallel for     | for             | +                                  |
+  // | parallel for     | simd            | *                                  |
+  // | parallel for     | sections        | +                                  |
+  // | parallel for     | section         | +                                  |
+  // | parallel for     | single          | +                                  |
+  // | parallel for     | parallel for    | *                                  |
+  // | parallel for     |parallel sections| *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | parallel sections| parallel        | *                                  |
+  // | parallel sections| for             | +                                  |
+  // | parallel sections| simd            | *                                  |
+  // | parallel sections| sections        | +                                  |
+  // | parallel sections| section         | *                                  |
+  // | parallel sections| single          | +                                  |
+  // | parallel sections| parallel for    | *                                  |
+  // | parallel sections|parallel sections| *                                  |
+  // +------------------+-----------------+------------------------------------+
+  if (Stack->getCurScope()) {
+    auto ParentRegion = Stack->getParentDirective();
+    bool NestingProhibited = false;
+    bool CloseNesting = true;
+    bool ShouldBeInParallelRegion = false;
+    if (isOpenMPSimdDirective(ParentRegion)) {
+      // OpenMP [2.16, Nesting of Regions]
+      // OpenMP constructs may not be nested inside a simd region.
+      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
+      return true;
+    }
+    if (CurrentRegion == OMPD_section) {
+      // OpenMP [2.7.2, sections Construct, Restrictions]
+      // Orphaned section directives are prohibited. That is, the section
+      // directives must appear within the sections construct and must not be
+      // encountered elsewhere in the sections region.
+      if (ParentRegion != OMPD_sections &&
+          ParentRegion != OMPD_parallel_sections) {
+        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
+            << (ParentRegion != OMPD_unknown)
+            << getOpenMPDirectiveName(ParentRegion);
+        return true;
+      }
+      return false;
+    }
+    if (isOpenMPWorksharingDirective(CurrentRegion) &&
+        !isOpenMPParallelDirective(CurrentRegion) &&
+        !isOpenMPSimdDirective(CurrentRegion)) {
+      // OpenMP [2.16, Nesting of Regions]
+      // A worksharing region may not be closely nested inside a worksharing,
+      // explicit task, critical, ordered, atomic, or master region.
+      // TODO
+      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) &&
+                          !isOpenMPSimdDirective(ParentRegion);
+      ShouldBeInParallelRegion = true;
+    }
+    if (NestingProhibited) {
+      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
+          << CloseNesting << getOpenMPDirectiveName(ParentRegion)
+          << ShouldBeInParallelRegion << getOpenMPDirectiveName(CurrentRegion);
+      return true;
+    }
+  }
+  return false;
+}
+
 StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
                                                 ArrayRef<OMPClause *> Clauses,
                                                 Stmt *AStmt,
@@ -712,6 +1125,8 @@
   assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   StmtResult Res = StmtError();
+  if (CheckNestingOfRegions(*this, DSAStack, Kind, StartLoc))
+    return StmtError();
 
   // Check default data sharing attributes for referenced variables.
   DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
@@ -719,6 +1134,7 @@
   if (DSAChecker.isErrorFound())
     return StmtError();
   // Generate list of implicitly defined firstprivate variables.
+  auto &VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
 
@@ -740,8 +1156,33 @@
                                        EndLoc);
     break;
   case OMPD_simd:
-    Res =
-        ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
+    Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
+                                   VarsWithInheritedDSA);
+    break;
+  case OMPD_for:
+    Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
+                                  VarsWithInheritedDSA);
+    break;
+  case OMPD_sections:
+    Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                       EndLoc);
+    break;
+  case OMPD_section:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses is allowed for 'omp section' directive");
+    Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
+    break;
+  case OMPD_single:
+    Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                     EndLoc);
+    break;
+  case OMPD_parallel_for:
+    Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                          EndLoc, VarsWithInheritedDSA);
+    break;
+  case OMPD_parallel_sections:
+    Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
+                                               StartLoc, EndLoc);
     break;
   case OMPD_threadprivate:
   case OMPD_task:
@@ -750,6 +1191,13 @@
     llvm_unreachable("Unknown OpenMP directive");
   }
 
+  for (auto P : VarsWithInheritedDSA) {
+    Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
+        << P.first << P.second->getSourceRange();
+  }
+  if (!VarsWithInheritedDSA.empty())
+    return StmtError();
+
   if (ErrorFound)
     return StmtError();
   return Res;
@@ -770,30 +1218,684 @@
 
   getCurFunction()->setHasBranchProtectedScope();
 
-  return Owned(
-      OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt));
+  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
+                                      AStmt);
 }
 
-StmtResult Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses,
-                                          Stmt *AStmt, SourceLocation StartLoc,
-                                          SourceLocation EndLoc) {
-  Stmt *CStmt = AStmt;
-  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(CStmt))
-    CStmt = CS->getCapturedStmt();
-  while (AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(CStmt))
-    CStmt = AS->getSubStmt();
-  ForStmt *For = dyn_cast<ForStmt>(CStmt);
+namespace {
+/// \brief Helper class for checking canonical form of the OpenMP loops and
+/// extracting iteration space of each loop in the loop nest, that will be used
+/// for IR generation.
+class OpenMPIterationSpaceChecker {
+  /// \brief Reference to Sema.
+  Sema &SemaRef;
+  /// \brief A location for diagnostics (when there is no some better location).
+  SourceLocation DefaultLoc;
+  /// \brief A location for diagnostics (when increment is not compatible).
+  SourceLocation ConditionLoc;
+  /// \brief A source location for referring to condition later.
+  SourceRange ConditionSrcRange;
+  /// \brief Loop variable.
+  VarDecl *Var;
+  /// \brief Lower bound (initializer for the var).
+  Expr *LB;
+  /// \brief Upper bound.
+  Expr *UB;
+  /// \brief Loop step (increment).
+  Expr *Step;
+  /// \brief This flag is true when condition is one of:
+  ///   Var <  UB
+  ///   Var <= UB
+  ///   UB  >  Var
+  ///   UB  >= Var
+  bool TestIsLessOp;
+  /// \brief This flag is true when condition is strict ( < or > ).
+  bool TestIsStrictOp;
+  /// \brief This flag is true when step is subtracted on each iteration.
+  bool SubtractStep;
+
+public:
+  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
+      : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
+        ConditionSrcRange(SourceRange()), Var(nullptr), LB(nullptr),
+        UB(nullptr), Step(nullptr), TestIsLessOp(false), TestIsStrictOp(false),
+        SubtractStep(false) {}
+  /// \brief Check init-expr for canonical loop form and save loop counter
+  /// variable - #Var and its initialization value - #LB.
+  bool CheckInit(Stmt *S);
+  /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
+  /// for less/greater and for strict/non-strict comparison.
+  bool CheckCond(Expr *S);
+  /// \brief Check incr-expr for canonical loop form and return true if it
+  /// does not conform, otherwise save loop step (#Step).
+  bool CheckInc(Expr *S);
+  /// \brief Return the loop counter variable.
+  VarDecl *GetLoopVar() const { return Var; }
+  /// \brief Return true if any expression is dependent.
+  bool Dependent() const;
+
+private:
+  /// \brief Check the right-hand side of an assignment in the increment
+  /// expression.
+  bool CheckIncRHS(Expr *RHS);
+  /// \brief Helper to set loop counter variable and its initializer.
+  bool SetVarAndLB(VarDecl *NewVar, Expr *NewLB);
+  /// \brief Helper to set upper bound.
+  bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR,
+             const SourceLocation &SL);
+  /// \brief Helper to set loop increment.
+  bool SetStep(Expr *NewStep, bool Subtract);
+};
+
+bool OpenMPIterationSpaceChecker::Dependent() const {
+  if (!Var) {
+    assert(!LB && !UB && !Step);
+    return false;
+  }
+  return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) ||
+         (UB && UB->isValueDependent()) || (Step && Step->isValueDependent());
+}
+
+bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, Expr *NewLB) {
+  // State consistency checking to ensure correct usage.
+  assert(Var == nullptr && LB == nullptr && UB == nullptr && Step == nullptr &&
+         !TestIsLessOp && !TestIsStrictOp);
+  if (!NewVar || !NewLB)
+    return true;
+  Var = NewVar;
+  LB = NewLB;
+  return false;
+}
+
+bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
+                                        const SourceRange &SR,
+                                        const SourceLocation &SL) {
+  // State consistency checking to ensure correct usage.
+  assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr &&
+         !TestIsLessOp && !TestIsStrictOp);
+  if (!NewUB)
+    return true;
+  UB = NewUB;
+  TestIsLessOp = LessOp;
+  TestIsStrictOp = StrictOp;
+  ConditionSrcRange = SR;
+  ConditionLoc = SL;
+  return false;
+}
+
+bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
+  // State consistency checking to ensure correct usage.
+  assert(Var != nullptr && LB != nullptr && Step == nullptr);
+  if (!NewStep)
+    return true;
+  if (!NewStep->isValueDependent()) {
+    // Check that the step is integer expression.
+    SourceLocation StepLoc = NewStep->getLocStart();
+    ExprResult Val =
+        SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
+    if (Val.isInvalid())
+      return true;
+    NewStep = Val.get();
+
+    // OpenMP [2.6, Canonical Loop Form, Restrictions]
+    //  If test-expr is of form var relational-op b and relational-op is < or
+    //  <= then incr-expr must cause var to increase on each iteration of the
+    //  loop. If test-expr is of form var relational-op b and relational-op is
+    //  > or >= then incr-expr must cause var to decrease on each iteration of
+    //  the loop.
+    //  If test-expr is of form b relational-op var and relational-op is < or
+    //  <= then incr-expr must cause var to decrease on each iteration of the
+    //  loop. If test-expr is of form b relational-op var and relational-op is
+    //  > or >= then incr-expr must cause var to increase on each iteration of
+    //  the loop.
+    llvm::APSInt Result;
+    bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
+    bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
+    bool IsConstNeg =
+        IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
+    bool IsConstZero = IsConstant && !Result.getBoolValue();
+    if (UB && (IsConstZero ||
+               (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
+                             : (!IsConstNeg || (IsUnsigned && !Subtract))))) {
+      SemaRef.Diag(NewStep->getExprLoc(),
+                   diag::err_omp_loop_incr_not_compatible)
+          << Var << TestIsLessOp << NewStep->getSourceRange();
+      SemaRef.Diag(ConditionLoc,
+                   diag::note_omp_loop_cond_requres_compatible_incr)
+          << TestIsLessOp << ConditionSrcRange;
+      return true;
+    }
+  }
+
+  Step = NewStep;
+  SubtractStep = Subtract;
+  return false;
+}
+
+bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S) {
+  // Check init-expr for canonical loop form and save loop counter
+  // variable - #Var and its initialization value - #LB.
+  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
+  //   var = lb
+  //   integer-type var = lb
+  //   random-access-iterator-type var = lb
+  //   pointer-type var = lb
+  //
+  if (!S) {
+    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
+    return true;
+  }
+  if (Expr *E = dyn_cast<Expr>(S))
+    S = E->IgnoreParens();
+  if (auto BO = dyn_cast<BinaryOperator>(S)) {
+    if (BO->getOpcode() == BO_Assign)
+      if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens()))
+        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), BO->getLHS());
+  } else if (auto DS = dyn_cast<DeclStmt>(S)) {
+    if (DS->isSingleDecl()) {
+      if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
+        if (Var->hasInit()) {
+          // Accept non-canonical init form here but emit ext. warning.
+          if (Var->getInitStyle() != VarDecl::CInit)
+            SemaRef.Diag(S->getLocStart(),
+                         diag::ext_omp_loop_not_canonical_init)
+                << S->getSourceRange();
+          return SetVarAndLB(Var, Var->getInit());
+        }
+      }
+    }
+  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S))
+    if (CE->getOperator() == OO_Equal)
+      if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0)))
+        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), CE->getArg(1));
+
+  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
+      << S->getSourceRange();
+  return true;
+}
+
+/// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
+/// variable (which may be the loop variable) if possible.
+static const VarDecl *GetInitVarDecl(const Expr *E) {
+  if (!E)
+    return nullptr;
+  E = E->IgnoreParenImpCasts();
+  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
+    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
+      if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 &&
+          CE->getArg(0) != nullptr)
+        E = CE->getArg(0)->IgnoreParenImpCasts();
+  auto DRE = dyn_cast_or_null<DeclRefExpr>(E);
+  if (!DRE)
+    return nullptr;
+  return dyn_cast<VarDecl>(DRE->getDecl());
+}
+
+bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
+  // Check test-expr for canonical form, save upper-bound UB, flags for
+  // less/greater and for strict/non-strict comparison.
+  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
+  //   var relational-op b
+  //   b relational-op var
+  //
+  if (!S) {
+    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var;
+    return true;
+  }
+  S = S->IgnoreParenImpCasts();
+  SourceLocation CondLoc = S->getLocStart();
+  if (auto BO = dyn_cast<BinaryOperator>(S)) {
+    if (BO->isRelationalOp()) {
+      if (GetInitVarDecl(BO->getLHS()) == Var)
+        return SetUB(BO->getRHS(),
+                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
+                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
+                     BO->getSourceRange(), BO->getOperatorLoc());
+      if (GetInitVarDecl(BO->getRHS()) == Var)
+        return SetUB(BO->getLHS(),
+                     (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
+                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
+                     BO->getSourceRange(), BO->getOperatorLoc());
+    }
+  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
+    if (CE->getNumArgs() == 2) {
+      auto Op = CE->getOperator();
+      switch (Op) {
+      case OO_Greater:
+      case OO_GreaterEqual:
+      case OO_Less:
+      case OO_LessEqual:
+        if (GetInitVarDecl(CE->getArg(0)) == Var)
+          return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
+                       Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
+                       CE->getOperatorLoc());
+        if (GetInitVarDecl(CE->getArg(1)) == Var)
+          return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
+                       Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
+                       CE->getOperatorLoc());
+        break;
+      default:
+        break;
+      }
+    }
+  }
+  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
+      << S->getSourceRange() << Var;
+  return true;
+}
+
+bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
+  // RHS of canonical loop form increment can be:
+  //   var + incr
+  //   incr + var
+  //   var - incr
+  //
+  RHS = RHS->IgnoreParenImpCasts();
+  if (auto BO = dyn_cast<BinaryOperator>(RHS)) {
+    if (BO->isAdditiveOp()) {
+      bool IsAdd = BO->getOpcode() == BO_Add;
+      if (GetInitVarDecl(BO->getLHS()) == Var)
+        return SetStep(BO->getRHS(), !IsAdd);
+      if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var)
+        return SetStep(BO->getLHS(), false);
+    }
+  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
+    bool IsAdd = CE->getOperator() == OO_Plus;
+    if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
+      if (GetInitVarDecl(CE->getArg(0)) == Var)
+        return SetStep(CE->getArg(1), !IsAdd);
+      if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var)
+        return SetStep(CE->getArg(0), false);
+    }
+  }
+  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
+      << RHS->getSourceRange() << Var;
+  return true;
+}
+
+bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
+  // Check incr-expr for canonical loop form and return true if it
+  // does not conform.
+  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
+  //   ++var
+  //   var++
+  //   --var
+  //   var--
+  //   var += incr
+  //   var -= incr
+  //   var = var + incr
+  //   var = incr + var
+  //   var = var - incr
+  //
+  if (!S) {
+    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;
+    return true;
+  }
+  S = S->IgnoreParens();
+  if (auto UO = dyn_cast<UnaryOperator>(S)) {
+    if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var)
+      return SetStep(
+          SemaRef.ActOnIntegerConstant(UO->getLocStart(),
+                                       (UO->isDecrementOp() ? -1 : 1)).get(),
+          false);
+  } else if (auto BO = dyn_cast<BinaryOperator>(S)) {
+    switch (BO->getOpcode()) {
+    case BO_AddAssign:
+    case BO_SubAssign:
+      if (GetInitVarDecl(BO->getLHS()) == Var)
+        return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
+      break;
+    case BO_Assign:
+      if (GetInitVarDecl(BO->getLHS()) == Var)
+        return CheckIncRHS(BO->getRHS());
+      break;
+    default:
+      break;
+    }
+  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
+    switch (CE->getOperator()) {
+    case OO_PlusPlus:
+    case OO_MinusMinus:
+      if (GetInitVarDecl(CE->getArg(0)) == Var)
+        return SetStep(
+            SemaRef.ActOnIntegerConstant(
+                        CE->getLocStart(),
+                        ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(),
+            false);
+      break;
+    case OO_PlusEqual:
+    case OO_MinusEqual:
+      if (GetInitVarDecl(CE->getArg(0)) == Var)
+        return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
+      break;
+    case OO_Equal:
+      if (GetInitVarDecl(CE->getArg(0)) == Var)
+        return CheckIncRHS(CE->getArg(1));
+      break;
+    default:
+      break;
+    }
+  }
+  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
+      << S->getSourceRange() << Var;
+  return true;
+}
+} // namespace
+
+/// \brief Called on a for stmt to check and extract its iteration space
+/// for further processing (such as collapsing).
+static bool CheckOpenMPIterationSpace(
+    OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
+    unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
+    Expr *NestedLoopCountExpr,
+    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  // OpenMP [2.6, Canonical Loop Form]
+  //   for (init-expr; test-expr; incr-expr) structured-block
+  auto For = dyn_cast_or_null<ForStmt>(S);
   if (!For) {
-    Diag(CStmt->getLocStart(), diag::err_omp_not_for)
-        << getOpenMPDirectiveName(OMPD_simd);
+    SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
+        << (NestedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind)
+        << NestedLoopCount << (CurrentNestedLoopCount > 0)
+        << CurrentNestedLoopCount;
+    if (NestedLoopCount > 1)
+      SemaRef.Diag(NestedLoopCountExpr->getExprLoc(),
+                   diag::note_omp_collapse_expr)
+          << NestedLoopCountExpr->getSourceRange();
+    return true;
+  }
+  assert(For->getBody());
+
+  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
+
+  // Check init.
+  auto Init = For->getInit();
+  if (ISC.CheckInit(Init)) {
+    return true;
+  }
+
+  bool HasErrors = false;
+
+  // Check loop variable's type.
+  auto Var = ISC.GetLoopVar();
+
+  // OpenMP [2.6, Canonical Loop Form]
+  // Var is one of the following:
+  //   A variable of signed or unsigned integer type.
+  //   For C++, a variable of a random access iterator type.
+  //   For C, a variable of a pointer type.
+  auto VarType = Var->getType();
+  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
+      !VarType->isPointerType() &&
+      !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
+    SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
+        << SemaRef.getLangOpts().CPlusPlus;
+    HasErrors = true;
+  }
+
+  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a
+  // Construct
+  // The loop iteration variable(s) in the associated for-loop(s) of a for or
+  // parallel for construct is (are) private.
+  // The loop iteration variable in the associated for-loop of a simd construct
+  // with just one associated for-loop is linear with a constant-linear-step
+  // that is the increment of the associated for-loop.
+  // Exclude loop var from the list of variables with implicitly defined data
+  // sharing attributes.
+  while (VarsWithImplicitDSA.count(Var) > 0)
+    VarsWithImplicitDSA.erase(Var);
+
+  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in
+  // a Construct, C/C++].
+  // The loop iteration variable in the associated for-loop of a simd construct
+  // with just one associated for-loop may be listed in a linear clause with a
+  // constant-linear-step that is the increment of the associated for-loop.
+  // The loop iteration variable(s) in the associated for-loop(s) of a for or
+  // parallel for construct may be listed in a private or lastprivate clause.
+  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var);
+  auto PredeterminedCKind =
+      isOpenMPSimdDirective(DKind)
+          ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
+          : OMPC_private;
+  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
+        DVar.CKind != PredeterminedCKind) ||
+       (isOpenMPWorksharingDirective(DKind) && DVar.CKind != OMPC_unknown &&
+        DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
+      (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
+    SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
+        << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
+        << getOpenMPClauseName(PredeterminedCKind);
+    ReportOriginalDSA(SemaRef, &DSA, Var, DVar, true);
+    HasErrors = true;
+  } else {
+    // Make the loop iteration variable private (for worksharing constructs),
+    // linear (for simd directives with the only one associated loop) or
+    // lastprivate (for simd directives with several collapsed loops).
+    DSA.addDSA(Var, nullptr, PredeterminedCKind);
+  }
+
+  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
+
+  // Check test-expr.
+  HasErrors |= ISC.CheckCond(For->getCond());
+
+  // Check incr-expr.
+  HasErrors |= ISC.CheckInc(For->getInc());
+
+  if (ISC.Dependent())
+    return HasErrors;
+
+  // FIXME: Build loop's iteration space representation.
+  return HasErrors;
+}
+
+/// \brief A helper routine to skip no-op (attributed, compound) stmts get the
+/// next nested for loop. If \a IgnoreCaptured is true, it skips captured stmt
+/// to get the first for loop.
+static Stmt *IgnoreContainerStmts(Stmt *S, bool IgnoreCaptured) {
+  if (IgnoreCaptured)
+    if (auto CapS = dyn_cast_or_null<CapturedStmt>(S))
+      S = CapS->getCapturedStmt();
+  // OpenMP [2.8.1, simd construct, Restrictions]
+  // All loops associated with the construct must be perfectly nested; that is,
+  // there must be no intervening code nor any OpenMP directive between any two
+  // loops.
+  while (true) {
+    if (auto AS = dyn_cast_or_null<AttributedStmt>(S))
+      S = AS->getSubStmt();
+    else if (auto CS = dyn_cast_or_null<CompoundStmt>(S)) {
+      if (CS->size() != 1)
+        break;
+      S = CS->body_back();
+    } else
+      break;
+  }
+  return S;
+}
+
+/// \brief Called on a for stmt to check itself and nested loops (if any).
+/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
+/// number of collapsed loops otherwise.
+static unsigned
+CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
+                Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA,
+                llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  unsigned NestedLoopCount = 1;
+  if (NestedLoopCountExpr) {
+    // Found 'collapse' clause - calculate collapse number.
+    llvm::APSInt Result;
+    if (NestedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
+      NestedLoopCount = Result.getLimitedValue();
+  }
+  // This is helper routine for loop directives (e.g., 'for', 'simd',
+  // 'for simd', etc.).
+  Stmt *CurStmt = IgnoreContainerStmts(AStmt, true);
+  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
+    if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
+                                  NestedLoopCount, NestedLoopCountExpr,
+                                  VarsWithImplicitDSA))
+      return 0;
+    // Move on to the next nested for loop, or to the loop body.
+    CurStmt = IgnoreContainerStmts(cast<ForStmt>(CurStmt)->getBody(), false);
+  }
+
+  // FIXME: Build resulting iteration space for IR generation (collapsing
+  // iteration spaces when loop count > 1 ('collapse' clause)).
+  return NestedLoopCount;
+}
+
+static Expr *GetCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
+  auto CollapseFilter = [](const OMPClause *C) -> bool {
+    return C->getClauseKind() == OMPC_collapse;
+  };
+  OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I(
+      Clauses, CollapseFilter);
+  if (I)
+    return cast<OMPCollapseClause>(*I)->getNumForLoops();
+  return nullptr;
+}
+
+StmtResult Sema::ActOnOpenMPSimdDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  // In presence of clause 'collapse', it will define the nested loops number.
+  unsigned NestedLoopCount =
+      CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this,
+                      *DSAStack, VarsWithImplicitDSA);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+                                  Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPForDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  // In presence of clause 'collapse', it will define the nested loops number.
+  unsigned NestedLoopCount =
+      CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this,
+                      *DSAStack, VarsWithImplicitDSA);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+                                 Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                              Stmt *AStmt,
+                                              SourceLocation StartLoc,
+                                              SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  auto BaseStmt = AStmt;
+  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
+    BaseStmt = CS->getCapturedStmt();
+  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
+    auto S = C->children();
+    if (!S)
+      return StmtError();
+    // All associated statements must be '#pragma omp section' except for
+    // the first one.
+    for (++S; S; ++S) {
+      auto SectionStmt = *S;
+      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
+        if (SectionStmt)
+          Diag(SectionStmt->getLocStart(),
+               diag::err_omp_sections_substmt_not_section);
+        return StmtError();
+      }
+    }
+  } else {
+    Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
     return StmtError();
   }
 
-  // FIXME: Checking loop canonical form, collapsing etc.
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses,
+                                      AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
+                                             SourceLocation StartLoc,
+                                             SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
 
   getCurFunction()->setHasBranchProtectedScope();
-  return Owned(
-      OMPSimdDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt));
+
+  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
+                                            Stmt *AStmt,
+                                            SourceLocation StartLoc,
+                                            SourceLocation EndLoc) {
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPParallelForDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
+  // 1.2.2 OpenMP Language Terminology
+  // Structured block - An executable statement with a single entry at the
+  // top and a single exit at the bottom.
+  // The point of exit cannot be a branch out of the structured block.
+  // longjmp() and throw() must not violate the entry/exit criteria.
+  CS->getCapturedDecl()->setNothrow();
+
+  // In presence of clause 'collapse', it will define the nested loops number.
+  unsigned NestedLoopCount =
+      CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt,
+                      *this, *DSAStack, VarsWithImplicitDSA);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
+                                         NestedLoopCount, Clauses, AStmt);
+}
+
+StmtResult
+Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                           Stmt *AStmt, SourceLocation StartLoc,
+                                           SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  auto BaseStmt = AStmt;
+  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
+    BaseStmt = CS->getCapturedStmt();
+  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
+    auto S = C->children();
+    if (!S)
+      return StmtError();
+    // All associated statements must be '#pragma omp section' except for
+    // the first one.
+    for (++S; S; ++S) {
+      auto SectionStmt = *S;
+      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
+        if (SectionStmt)
+          Diag(SectionStmt->getLocStart(),
+               diag::err_omp_parallel_sections_substmt_not_section);
+        return StmtError();
+      }
+    }
+  } else {
+    Diag(AStmt->getLocStart(),
+         diag::err_omp_parallel_sections_not_compound_stmt);
+    return StmtError();
+  }
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc,
+                                              Clauses, AStmt);
 }
 
 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
@@ -816,11 +1918,18 @@
     break;
   case OMPC_default:
   case OMPC_proc_bind:
+  case OMPC_schedule:
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
+  case OMPC_reduction:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
   case OMPC_threadprivate:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
@@ -840,14 +1949,14 @@
     if (Val.isInvalid())
       return nullptr;
 
-    ValExpr = Val.take();
+    ValExpr = Val.get();
   }
 
   return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc);
 }
 
-ExprResult Sema::PerformImplicitIntegerConversion(SourceLocation Loc,
-                                                  Expr *Op) {
+ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
+                                                        Expr *Op) {
   if (!Op)
     return ExprError();
 
@@ -900,11 +2009,11 @@
       !NumThreads->containsUnexpandedParameterPack()) {
     SourceLocation NumThreadsLoc = NumThreads->getLocStart();
     ExprResult Val =
-        PerformImplicitIntegerConversion(NumThreadsLoc, NumThreads);
+        PerformOpenMPImplicitIntegerConversion(NumThreadsLoc, NumThreads);
     if (Val.isInvalid())
       return nullptr;
 
-    ValExpr = Val.take();
+    ValExpr = Val.get();
 
     // OpenMP [2.5, Restrictions]
     //  The num_threads expression must evaluate to a positive integer value.
@@ -927,7 +2036,7 @@
     return ExprError();
   if (E->isValueDependent() || E->isTypeDependent() ||
       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
-    return Owned(E);
+    return E;
   llvm::APSInt Result;
   ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
   if (ICE.isInvalid())
@@ -950,21 +2059,24 @@
   if (Safelen.isInvalid())
     return nullptr;
   return new (Context)
-      OMPSafelenClause(Safelen.take(), StartLoc, LParenLoc, EndLoc);
+      OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
 }
 
-OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
+                                           SourceLocation StartLoc,
                                            SourceLocation LParenLoc,
                                            SourceLocation EndLoc) {
+  // OpenMP [2.7.1, loop construct, Description]
   // OpenMP [2.8.1, simd construct, Description]
+  // OpenMP [2.9.6, distribute construct, Description]
   // The parameter of the collapse clause must be a constant
   // positive integer expression.
-  ExprResult NumForLoops =
-      VerifyPositiveIntegerConstantInClause(Num, OMPC_collapse);
-  if (NumForLoops.isInvalid())
+  ExprResult NumForLoopsResult =
+      VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
+  if (NumForLoopsResult.isInvalid())
     return nullptr;
   return new (Context)
-      OMPCollapseClause(NumForLoops.take(), StartLoc, LParenLoc, EndLoc);
+      OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
 }
 
 OMPClause *Sema::ActOnOpenMPSimpleClause(
@@ -986,11 +2098,18 @@
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_collapse:
+  case OMPC_schedule:
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
+  case OMPC_reduction:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
   case OMPC_threadprivate:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
@@ -1029,10 +2148,10 @@
   }
   switch (Kind) {
   case OMPC_DEFAULT_none:
-    DSAStack->setDefaultDSANone();
+    DSAStack->setDefaultDSANone(KindKwLoc);
     break;
   case OMPC_DEFAULT_shared:
-    DSAStack->setDefaultDSAShared();
+    DSAStack->setDefaultDSAShared(KindKwLoc);
     break;
   case OMPC_DEFAULT_unknown:
     llvm_unreachable("Clause kind is not allowed.");
@@ -1073,11 +2192,147 @@
       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
 }
 
-OMPClause *
-Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> VarList,
-                               Expr *TailExpr, SourceLocation StartLoc,
-                               SourceLocation LParenLoc,
-                               SourceLocation ColonLoc, SourceLocation EndLoc) {
+OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
+    OpenMPClauseKind Kind, unsigned Argument, Expr *Expr,
+    SourceLocation StartLoc, SourceLocation LParenLoc,
+    SourceLocation ArgumentLoc, SourceLocation CommaLoc,
+    SourceLocation EndLoc) {
+  OMPClause *Res = nullptr;
+  switch (Kind) {
+  case OMPC_schedule:
+    Res = ActOnOpenMPScheduleClause(
+        static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc,
+        LParenLoc, ArgumentLoc, CommaLoc, EndLoc);
+    break;
+  case OMPC_if:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
+  case OMPC_default:
+  case OMPC_proc_bind:
+  case OMPC_private:
+  case OMPC_firstprivate:
+  case OMPC_lastprivate:
+  case OMPC_shared:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_threadprivate:
+  case OMPC_unknown:
+    llvm_unreachable("Clause is not allowed.");
+  }
+  return Res;
+}
+
+OMPClause *Sema::ActOnOpenMPScheduleClause(
+    OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
+    SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
+    SourceLocation EndLoc) {
+  if (Kind == OMPC_SCHEDULE_unknown) {
+    std::string Values;
+    std::string Sep(", ");
+    for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) {
+      Values += "'";
+      Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i);
+      Values += "'";
+      switch (i) {
+      case OMPC_SCHEDULE_unknown - 2:
+        Values += " or ";
+        break;
+      case OMPC_SCHEDULE_unknown - 1:
+        break;
+      default:
+        Values += Sep;
+        break;
+      }
+    }
+    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+        << Values << getOpenMPClauseName(OMPC_schedule);
+    return nullptr;
+  }
+  Expr *ValExpr = ChunkSize;
+  if (ChunkSize) {
+    if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
+        !ChunkSize->isInstantiationDependent() &&
+        !ChunkSize->containsUnexpandedParameterPack()) {
+      SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
+      ExprResult Val =
+          PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
+      if (Val.isInvalid())
+        return nullptr;
+
+      ValExpr = Val.get();
+
+      // OpenMP [2.7.1, Restrictions]
+      //  chunk_size must be a loop invariant integer expression with a positive
+      //  value.
+      llvm::APSInt Result;
+      if (ValExpr->isIntegerConstantExpr(Result, Context) &&
+          Result.isSigned() && !Result.isStrictlyPositive()) {
+        Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
+            << "schedule" << ChunkSize->getSourceRange();
+        return nullptr;
+      }
+    }
+  }
+
+  return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc,
+                                         EndLoc, Kind, ValExpr);
+}
+
+OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
+                                   SourceLocation StartLoc,
+                                   SourceLocation EndLoc) {
+  OMPClause *Res = nullptr;
+  switch (Kind) {
+  case OMPC_ordered:
+    Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
+    break;
+  case OMPC_nowait:
+    Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
+    break;
+  case OMPC_if:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
+  case OMPC_schedule:
+  case OMPC_private:
+  case OMPC_firstprivate:
+  case OMPC_lastprivate:
+  case OMPC_shared:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_default:
+  case OMPC_proc_bind:
+  case OMPC_threadprivate:
+  case OMPC_unknown:
+    llvm_unreachable("Clause is not allowed.");
+  }
+  return Res;
+}
+
+OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
+                                          SourceLocation EndLoc) {
+  return new (Context) OMPOrderedClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
+                                         SourceLocation EndLoc) {
+  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPVarListClause(
+    OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
+    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
+    SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
+    const DeclarationNameInfo &ReductionId) {
   OMPClause *Res = nullptr;
   switch (Kind) {
   case OMPC_private:
@@ -1086,22 +2341,39 @@
   case OMPC_firstprivate:
     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_lastprivate:
+    Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
+    break;
   case OMPC_shared:
     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_reduction:
+    Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
+                                     EndLoc, ReductionIdScopeSpec, ReductionId);
+    break;
   case OMPC_linear:
     Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
                                   ColonLoc, EndLoc);
     break;
+  case OMPC_aligned:
+    Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
+                                   ColonLoc, EndLoc);
+    break;
   case OMPC_copyin:
     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_copyprivate:
+    Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
+    break;
   case OMPC_if:
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_collapse:
   case OMPC_default:
   case OMPC_proc_bind:
+  case OMPC_schedule:
+  case OMPC_ordered:
+  case OMPC_nowait:
   case OMPC_threadprivate:
   case OMPC_unknown:
     llvm_unreachable("Clause is not allowed.");
@@ -1163,7 +2435,7 @@
 
     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
     //  A variable of class type (or array thereof) that appears in a private
-    //  clause requires an accesible, unambiguous default constructor for the
+    //  clause requires an accessible, unambiguous default constructor for the
     //  class type.
     while (Type.getNonReferenceType()->isArrayType()) {
       Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr())
@@ -1172,13 +2444,16 @@
     CXXRecordDecl *RD = getLangOpts().CPlusPlus
                             ? Type.getNonReferenceType()->getAsCXXRecordDecl()
                             : nullptr;
+    // FIXME This code must be replaced by actual constructing/destructing of
+    // the private variable.
     if (RD) {
       CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
       PartialDiagnostic PD =
           PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
-      if (!CD || CheckConstructorAccess(
-                     ELoc, CD, InitializedEntity::InitializeTemporary(Type),
-                     CD->getAccess(), PD) == AR_inaccessible ||
+      if (!CD ||
+          CheckConstructorAccess(ELoc, CD,
+                                 InitializedEntity::InitializeTemporary(Type),
+                                 CD->getAccess(), PD) == AR_inaccessible ||
           CD->isDeleted()) {
         Diag(ELoc, diag::err_omp_required_method)
             << getOpenMPClauseName(OMPC_private) << 0;
@@ -1223,13 +2498,7 @@
     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
                                           << getOpenMPClauseName(OMPC_private);
-      if (DVar.RefExpr) {
-        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
-            << getOpenMPClauseName(DVar.CKind);
-      } else {
-        Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
-            << getOpenMPClauseName(DVar.CKind);
-      }
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
       continue;
     }
 
@@ -1297,19 +2566,22 @@
 
     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
     //  A variable of class type (or array thereof) that appears in a private
-    //  clause requires an accesible, unambiguous copy constructor for the
+    //  clause requires an accessible, unambiguous copy constructor for the
     //  class type.
     Type = Context.getBaseElementType(Type);
     CXXRecordDecl *RD = getLangOpts().CPlusPlus
                             ? Type.getNonReferenceType()->getAsCXXRecordDecl()
                             : nullptr;
+    // FIXME This code must be replaced by actual constructing/destructing of
+    // the firstprivate variable.
     if (RD) {
       CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0);
       PartialDiagnostic PD =
           PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
-      if (!CD || CheckConstructorAccess(
-                     ELoc, CD, InitializedEntity::InitializeTemporary(Type),
-                     CD->getAccess(), PD) == AR_inaccessible ||
+      if (!CD ||
+          CheckConstructorAccess(ELoc, CD,
+                                 InitializedEntity::InitializeTemporary(Type),
+                                 CD->getAccess(), PD) == AR_inaccessible ||
           CD->isDeleted()) {
         Diag(ELoc, diag::err_omp_required_method)
             << getOpenMPClauseName(OMPC_firstprivate) << 1;
@@ -1354,14 +2626,12 @@
       //  A list item that specifies a given variable may not appear in more
       // than one clause on the same directive, except that a variable may be
       //  specified in both firstprivate and lastprivate clauses.
-      //  TODO: add processing for lastprivate.
       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
-          DVar.RefExpr) {
+          DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
         Diag(ELoc, diag::err_omp_wrong_dsa)
             << getOpenMPClauseName(DVar.CKind)
             << getOpenMPClauseName(OMPC_firstprivate);
-        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
-            << getOpenMPClauseName(DVar.CKind);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
         continue;
       }
 
@@ -1381,28 +2651,40 @@
         Diag(ELoc, diag::err_omp_wrong_dsa)
             << getOpenMPClauseName(DVar.CKind)
             << getOpenMPClauseName(OMPC_firstprivate);
-        Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
-            << getOpenMPClauseName(DVar.CKind);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
         continue;
       }
 
+      OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
       // OpenMP [2.9.3.4, Restrictions, p.2]
       //  A list item that is private within a parallel region must not appear
       //  in a firstprivate clause on a worksharing construct if any of the
       //  worksharing regions arising from the worksharing construct ever bind
       //  to any of the parallel regions arising from the parallel construct.
+      if (isOpenMPWorksharingDirective(CurrDir) &&
+          !isOpenMPParallelDirective(CurrDir)) {
+        DVar = DSAStack->getImplicitDSA(VD);
+        if (DVar.CKind != OMPC_shared) {
+          Diag(ELoc, diag::err_omp_required_access)
+              << getOpenMPClauseName(OMPC_firstprivate)
+              << getOpenMPClauseName(OMPC_shared);
+          ReportOriginalDSA(*this, DSAStack, VD, DVar);
+          continue;
+        }
+      }
       // OpenMP [2.9.3.4, Restrictions, p.3]
       //  A list item that appears in a reduction clause of a parallel construct
       //  must not appear in a firstprivate clause on a worksharing or task
       //  construct if any of the worksharing or task regions arising from the
       //  worksharing or task construct ever bind to any of the parallel regions
       //  arising from the parallel construct.
+      // TODO
       // OpenMP [2.9.3.4, Restrictions, p.4]
       //  A list item that appears in a reduction clause in worksharing
       //  construct must not appear in a firstprivate clause in a task construct
       //  encountered during execution of any of the worksharing regions arising
       //  from the worksharing construct.
-      // TODO:
+      // TODO
     }
 
     DSAStack->addDSA(VD, DE, OMPC_firstprivate);
@@ -1416,6 +2698,161 @@
                                        Vars);
 }
 
+OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
+                                              SourceLocation StartLoc,
+                                              SourceLocation LParenLoc,
+                                              SourceLocation EndLoc) {
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    // OpenMP  [2.14.3.5, Restrictions, p.1]
+    //  A variable that is part of another variable (as an array or structure
+    //  element) cannot appear in a lastprivate clause.
+    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+    Decl *D = DE->getDecl();
+    VarDecl *VD = cast<VarDecl>(D);
+
+    QualType Type = VD->getType();
+    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
+      // It will be analyzed later.
+      Vars.push_back(DE);
+      continue;
+    }
+
+    // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
+    //  A variable that appears in a lastprivate clause must not have an
+    //  incomplete type or a reference type.
+    if (RequireCompleteType(ELoc, Type,
+                            diag::err_omp_lastprivate_incomplete_type)) {
+      continue;
+    }
+    if (Type->isReferenceType()) {
+      Diag(ELoc, diag::err_omp_clause_ref_type_arg)
+          << getOpenMPClauseName(OMPC_lastprivate) << Type;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
+    // in a Construct]
+    //  Variables with the predetermined data-sharing attributes may not be
+    //  listed in data-sharing attributes clauses, except for the cases
+    //  listed below.
+    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
+    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
+        DVar.CKind != OMPC_firstprivate &&
+        (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
+      Diag(ELoc, diag::err_omp_wrong_dsa)
+          << getOpenMPClauseName(DVar.CKind)
+          << getOpenMPClauseName(OMPC_lastprivate);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
+      continue;
+    }
+
+    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
+    // OpenMP [2.14.3.5, Restrictions, p.2]
+    // A list item that is private within a parallel region, or that appears in
+    // the reduction clause of a parallel construct, must not appear in a
+    // lastprivate clause on a worksharing construct if any of the corresponding
+    // worksharing regions ever binds to any of the corresponding parallel
+    // regions.
+    if (isOpenMPWorksharingDirective(CurrDir) &&
+        !isOpenMPParallelDirective(CurrDir)) {
+      DVar = DSAStack->getImplicitDSA(VD);
+      if (DVar.CKind != OMPC_shared) {
+        Diag(ELoc, diag::err_omp_required_access)
+            << getOpenMPClauseName(OMPC_lastprivate)
+            << getOpenMPClauseName(OMPC_shared);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
+        continue;
+      }
+    }
+    // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
+    //  A variable of class type (or array thereof) that appears in a
+    //  lastprivate clause requires an accessible, unambiguous default
+    //  constructor for the class type, unless the list item is also specified
+    //  in a firstprivate clause.
+    //  A variable of class type (or array thereof) that appears in a
+    //  lastprivate clause requires an accessible, unambiguous copy assignment
+    //  operator for the class type.
+    while (Type.getNonReferenceType()->isArrayType())
+      Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr())
+                 ->getElementType();
+    CXXRecordDecl *RD = getLangOpts().CPlusPlus
+                            ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+                            : nullptr;
+    // FIXME This code must be replaced by actual copying and destructing of the
+    // lastprivate variable.
+    if (RD) {
+      CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
+      DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
+      if (MD) {
+        if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+            MD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_lastprivate) << 2;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, MD);
+        DiagnoseUseOfDecl(MD, ELoc);
+      }
+
+      CXXDestructorDecl *DD = RD->getDestructor();
+      if (DD) {
+        PartialDiagnostic PD =
+            PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+        if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
+            DD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_lastprivate) << 4;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, DD);
+        DiagnoseUseOfDecl(DD, ELoc);
+      }
+    }
+
+    if (DVar.CKind != OMPC_firstprivate)
+      DSAStack->addDSA(VD, DE, OMPC_lastprivate);
+    Vars.push_back(DE);
+  }
+
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
+                                      Vars);
+}
+
 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
@@ -1463,8 +2900,7 @@
         DVar.RefExpr) {
       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
                                           << getOpenMPClauseName(OMPC_shared);
-      Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
-          << getOpenMPClauseName(DVar.CKind);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
       continue;
     }
 
@@ -1478,6 +2914,327 @@
   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
 }
 
+namespace {
+class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
+  DSAStackTy *Stack;
+
+public:
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+    if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
+      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD);
+      if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
+        return false;
+      if (DVar.CKind != OMPC_unknown)
+        return true;
+      DSAStackTy::DSAVarData DVarPrivate =
+          Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways());
+      if (DVarPrivate.CKind != OMPC_unknown)
+        return true;
+      return false;
+    }
+    return false;
+  }
+  bool VisitStmt(Stmt *S) {
+    for (auto Child : S->children()) {
+      if (Child && Visit(Child))
+        return true;
+    }
+    return false;
+  }
+  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
+};
+} // namespace
+
+OMPClause *Sema::ActOnOpenMPReductionClause(
+    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
+    SourceLocation ColonLoc, SourceLocation EndLoc,
+    CXXScopeSpec &ReductionIdScopeSpec,
+    const DeclarationNameInfo &ReductionId) {
+  // TODO: Allow scope specification search when 'declare reduction' is
+  // supported.
+  assert(ReductionIdScopeSpec.isEmpty() &&
+         "No support for scoped reduction identifiers yet.");
+
+  auto DN = ReductionId.getName();
+  auto OOK = DN.getCXXOverloadedOperator();
+  BinaryOperatorKind BOK = BO_Comma;
+
+  // OpenMP [2.14.3.6, reduction clause]
+  // C
+  // reduction-identifier is either an identifier or one of the following
+  // operators: +, -, *,  &, |, ^, && and ||
+  // C++
+  // reduction-identifier is either an id-expression or one of the following
+  // operators: +, -, *, &, |, ^, && and ||
+  // FIXME: Only 'min' and 'max' identifiers are supported for now.
+  switch (OOK) {
+  case OO_Plus:
+  case OO_Minus:
+    BOK = BO_AddAssign;
+    break;
+  case OO_Star:
+    BOK = BO_MulAssign;
+    break;
+  case OO_Amp:
+    BOK = BO_AndAssign;
+    break;
+  case OO_Pipe:
+    BOK = BO_OrAssign;
+    break;
+  case OO_Caret:
+    BOK = BO_XorAssign;
+    break;
+  case OO_AmpAmp:
+    BOK = BO_LAnd;
+    break;
+  case OO_PipePipe:
+    BOK = BO_LOr;
+    break;
+  default:
+    if (auto II = DN.getAsIdentifierInfo()) {
+      if (II->isStr("max"))
+        BOK = BO_GT;
+      else if (II->isStr("min"))
+        BOK = BO_LT;
+    }
+    break;
+  }
+  SourceRange ReductionIdRange;
+  if (ReductionIdScopeSpec.isValid()) {
+    ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
+  }
+  ReductionIdRange.setEnd(ReductionId.getEndLoc());
+  if (BOK == BO_Comma) {
+    // Not allowed reduction identifier is found.
+    Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier)
+        << ReductionIdRange;
+    return nullptr;
+  }
+
+  SmallVector<Expr *, 8> Vars;
+  for (auto RefExpr : VarList) {
+    assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
+        RefExpr->isInstantiationDependent() ||
+        RefExpr->containsUnexpandedParameterPack()) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    auto ELoc = RefExpr->getExprLoc();
+    auto ERange = RefExpr->getSourceRange();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable or array section, subject to the restrictions
+    //  specified in Section 2.4 on page 42 and in each of the sections
+    // describing clauses and directives for which a list appears.
+    // OpenMP  [2.14.3.3, Restrictions, p.1]
+    //  A variable that is part of another variable (as an array or
+    //  structure element) cannot appear in a private clause.
+    auto DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << ERange;
+      continue;
+    }
+    auto D = DE->getDecl();
+    auto VD = cast<VarDecl>(D);
+    auto Type = VD->getType();
+    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
+    //  A variable that appears in a private clause must not have an incomplete
+    //  type or a reference type.
+    if (RequireCompleteType(ELoc, Type,
+                            diag::err_omp_reduction_incomplete_type))
+      continue;
+    // OpenMP [2.14.3.6, reduction clause, Restrictions]
+    // Arrays may not appear in a reduction clause.
+    if (Type.getNonReferenceType()->isArrayType()) {
+      Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+    // OpenMP [2.14.3.6, reduction clause, Restrictions]
+    // A list item that appears in a reduction clause must not be
+    // const-qualified.
+    if (Type.getNonReferenceType().isConstant(Context)) {
+      Diag(ELoc, diag::err_omp_const_variable)
+          << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+    // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
+    //  If a list-item is a reference type then it must bind to the same object
+    //  for all threads of the team.
+    VarDecl *VDDef = VD->getDefinition();
+    if (Type->isReferenceType() && VDDef) {
+      DSARefChecker Check(DSAStack);
+      if (Check.Visit(VDDef->getInit())) {
+        Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
+        Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
+        continue;
+      }
+    }
+    // OpenMP [2.14.3.6, reduction clause, Restrictions]
+    // The type of a list item that appears in a reduction clause must be valid
+    // for the reduction-identifier. For a max or min reduction in C, the type
+    // of the list item must be an allowed arithmetic data type: char, int,
+    // float, double, or _Bool, possibly modified with long, short, signed, or
+    // unsigned. For a max or min reduction in C++, the type of the list item
+    // must be an allowed arithmetic data type: char, wchar_t, int, float,
+    // double, or bool, possibly modified with long, short, signed, or unsigned.
+    if ((BOK == BO_GT || BOK == BO_LT) &&
+        !(Type->isScalarType() ||
+          (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
+      Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
+          << getLangOpts().CPlusPlus;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+    if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
+        !getLangOpts().CPlusPlus && Type->isFloatingType()) {
+      Diag(ELoc, diag::err_omp_clause_floating_type_arg);
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+    bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
+    getDiagnostics().setSuppressAllDiagnostics(true);
+    ExprResult ReductionOp =
+        BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK,
+                   RefExpr, RefExpr);
+    getDiagnostics().setSuppressAllDiagnostics(Suppress);
+    if (ReductionOp.isInvalid()) {
+      Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
+                                                            << ReductionIdRange;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
+    // in a Construct]
+    //  Variables with the predetermined data-sharing attributes may not be
+    //  listed in data-sharing attributes clauses, except for the cases
+    //  listed below. For these exceptions only, listing a predetermined
+    //  variable in a data-sharing attribute clause is allowed and overrides
+    //  the variable's predetermined data-sharing attributes.
+    // OpenMP [2.14.3.6, Restrictions, p.3]
+    //  Any number of reduction clauses can be specified on the directive,
+    //  but a list item can appear only once in the reduction clauses for that
+    //  directive.
+    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
+    if (DVar.CKind == OMPC_reduction) {
+      Diag(ELoc, diag::err_omp_once_referenced)
+          << getOpenMPClauseName(OMPC_reduction);
+      if (DVar.RefExpr) {
+        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
+      }
+    } else if (DVar.CKind != OMPC_unknown) {
+      Diag(ELoc, diag::err_omp_wrong_dsa)
+          << getOpenMPClauseName(DVar.CKind)
+          << getOpenMPClauseName(OMPC_reduction);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
+      continue;
+    }
+
+    // OpenMP [2.14.3.6, Restrictions, p.1]
+    //  A list item that appears in a reduction clause of a worksharing
+    //  construct must be shared in the parallel regions to which any of the
+    //  worksharing regions arising from the worksharing construct bind.
+    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
+    if (isOpenMPWorksharingDirective(CurrDir) &&
+        !isOpenMPParallelDirective(CurrDir)) {
+      DVar = DSAStack->getImplicitDSA(VD);
+      if (DVar.CKind != OMPC_shared) {
+        Diag(ELoc, diag::err_omp_required_access)
+            << getOpenMPClauseName(OMPC_reduction)
+            << getOpenMPClauseName(OMPC_shared);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
+        continue;
+      }
+    }
+
+    CXXRecordDecl *RD = getLangOpts().CPlusPlus
+                            ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+                            : nullptr;
+    // FIXME This code must be replaced by actual constructing/destructing of
+    // the reduction variable.
+    if (RD) {
+      CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
+      PartialDiagnostic PD =
+          PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+      if (!CD ||
+          CheckConstructorAccess(ELoc, CD,
+                                 InitializedEntity::InitializeTemporary(Type),
+                                 CD->getAccess(), PD) == AR_inaccessible ||
+          CD->isDeleted()) {
+        Diag(ELoc, diag::err_omp_required_method)
+            << getOpenMPClauseName(OMPC_reduction) << 0;
+        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                      VarDecl::DeclarationOnly;
+        Diag(VD->getLocation(),
+             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+            << VD;
+        Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+        continue;
+      }
+      MarkFunctionReferenced(ELoc, CD);
+      DiagnoseUseOfDecl(CD, ELoc);
+
+      CXXDestructorDecl *DD = RD->getDestructor();
+      if (DD) {
+        if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
+            DD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_reduction) << 4;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, DD);
+        DiagnoseUseOfDecl(DD, ELoc);
+      }
+    }
+
+    DSAStack->addDSA(VD, DE, OMPC_reduction);
+    Vars.push_back(DE);
+  }
+
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPReductionClause::Create(
+      Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
+      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId);
+}
+
 OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
@@ -1522,8 +3279,7 @@
     if (DVar.RefExpr) {
       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
                                           << getOpenMPClauseName(OMPC_linear);
-      Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
-          << getOpenMPClauseName(DVar.CKind);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
       continue;
     }
 
@@ -1588,10 +3344,10 @@
       !Step->isInstantiationDependent() &&
       !Step->containsUnexpandedParameterPack()) {
     SourceLocation StepLoc = Step->getLocStart();
-    ExprResult Val = PerformImplicitIntegerConversion(StepLoc, Step);
+    ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
     if (Val.isInvalid())
       return nullptr;
-    StepExpr = Val.take();
+    StepExpr = Val.get();
 
     // Warn about zero linear step (it would be probably better specified as
     // making corresponding variables 'const').
@@ -1606,6 +3362,81 @@
                                  Vars, StepExpr);
 }
 
+OMPClause *Sema::ActOnOpenMPAlignedClause(
+    ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
+    SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
+
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP aligned clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+
+    VarDecl *VD = cast<VarDecl>(DE->getDecl());
+
+    // OpenMP  [2.8.1, simd construct, Restrictions]
+    // The type of list items appearing in the aligned clause must be
+    // array, pointer, reference to array, or reference to pointer.
+    QualType QType = DE->getType()
+                         .getNonReferenceType()
+                         .getUnqualifiedType()
+                         .getCanonicalType();
+    const Type *Ty = QType.getTypePtrOrNull();
+    if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() &&
+                !Ty->isPointerType())) {
+      Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
+          << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange();
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // OpenMP  [2.8.1, simd construct, Restrictions]
+    // A list-item cannot appear in more than one aligned clause.
+    if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) {
+      Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
+      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
+          << getOpenMPClauseName(OMPC_aligned);
+      continue;
+    }
+
+    Vars.push_back(DE);
+  }
+
+  // OpenMP [2.8.1, simd construct, Description]
+  // The parameter of the aligned clause, alignment, must be a constant
+  // positive integer expression.
+  // If no optional parameter is specified, implementation-defined default
+  // alignments for SIMD instructions on the target platforms are assumed.
+  if (Alignment != nullptr) {
+    ExprResult AlignResult =
+        VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
+    if (AlignResult.isInvalid())
+      return nullptr;
+    Alignment = AlignResult.get();
+  }
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
+                                  EndLoc, Vars, Alignment);
+}
+
 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
@@ -1651,28 +3482,32 @@
 
     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
     //  A variable of class type (or array thereof) that appears in a
-    //  copyin clause requires an accesible, unambiguous copy assignment
+    //  copyin clause requires an accessible, unambiguous copy assignment
     //  operator for the class type.
     Type = Context.getBaseElementType(Type);
     CXXRecordDecl *RD =
         getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+    // FIXME This code must be replaced by actual assignment of the
+    // threadprivate variable.
     if (RD) {
       CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
       DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
-      if (!MD || CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
-          MD->isDeleted()) {
-        Diag(ELoc, diag::err_omp_required_method)
-            << getOpenMPClauseName(OMPC_copyin) << 2;
-        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                      VarDecl::DeclarationOnly;
-        Diag(VD->getLocation(),
-             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
-            << VD;
-        Diag(RD->getLocation(), diag::note_previous_decl) << RD;
-        continue;
+      if (MD) {
+        if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+            MD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_copyin) << 2;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, MD);
+        DiagnoseUseOfDecl(MD, ELoc);
       }
-      MarkFunctionReferenced(ELoc, MD);
-      DiagnoseUseOfDecl(MD, ELoc);
     }
 
     DSAStack->addDSA(VD, DE, OMPC_copyin);
@@ -1685,4 +3520,108 @@
   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
 }
 
+OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
+                                              SourceLocation StartLoc,
+                                              SourceLocation LParenLoc,
+                                              SourceLocation EndLoc) {
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP copyprivate clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    // OpenMP  [2.14.4.1, Restrictions, p.1]
+    //  A list item that appears in a copyin clause must be threadprivate.
+    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+
+    Decl *D = DE->getDecl();
+    VarDecl *VD = cast<VarDecl>(D);
+
+    QualType Type = VD->getType();
+    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
+      // It will be analyzed later.
+      Vars.push_back(DE);
+      continue;
+    }
+
+    // OpenMP [2.14.4.2, Restrictions, p.2]
+    //  A list item that appears in a copyprivate clause may not appear in a
+    //  private or firstprivate clause on the single construct.
+    if (!DSAStack->isThreadPrivate(VD)) {
+      auto DVar = DSAStack->getTopDSA(VD);
+      if (DVar.CKind != OMPC_copyprivate && DVar.CKind != OMPC_unknown &&
+          !(DVar.CKind == OMPC_private && !DVar.RefExpr)) {
+        Diag(ELoc, diag::err_omp_wrong_dsa)
+            << getOpenMPClauseName(DVar.CKind)
+            << getOpenMPClauseName(OMPC_copyprivate);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
+        continue;
+      }
+
+      // OpenMP [2.11.4.2, Restrictions, p.1]
+      //  All list items that appear in a copyprivate clause must be either
+      //  threadprivate or private in the enclosing context.
+      if (DVar.CKind == OMPC_unknown) {
+        DVar = DSAStack->getImplicitDSA(VD);
+        if (DVar.CKind == OMPC_shared) {
+          Diag(ELoc, diag::err_omp_required_access)
+              << getOpenMPClauseName(OMPC_copyprivate)
+              << "threadprivate or private in the enclosing context";
+          ReportOriginalDSA(*this, DSAStack, VD, DVar);
+          continue;
+        }
+      }
+    }
+
+    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
+    //  A variable of class type (or array thereof) that appears in a
+    //  copyin clause requires an accessible, unambiguous copy assignment
+    //  operator for the class type.
+    Type = Context.getBaseElementType(Type);
+    CXXRecordDecl *RD =
+        getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+    // FIXME This code must be replaced by actual assignment of the
+    // threadprivate variable.
+    if (RD) {
+      CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
+      DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
+      if (MD) {
+        if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+            MD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_copyprivate) << 2;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, MD);
+        DiagnoseUseOfDecl(MD, ELoc);
+      }
+    }
+
+    // No need to mark vars as copyprivate, they are already threadprivate or
+    // implicitly private.
+    Vars.push_back(DE);
+  }
+
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
+}
+
 #undef DSAStack
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 147325b..4eed8c1 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -61,8 +61,8 @@
 
   S.MarkDeclRefReferenced(DRE);
 
-  ExprResult E = S.Owned(DRE);
-  E = S.DefaultFunctionArrayConversion(E.take());
+  ExprResult E = DRE;
+  E = S.DefaultFunctionArrayConversion(E.get());
   if (E.isInvalid())
     return ExprError();
   return E;
@@ -851,7 +851,7 @@
     if (result.isInvalid())
       return true;
 
-    E = result.take();
+    E = result.get();
     return false;
   }
 
@@ -4557,7 +4557,7 @@
     InitializedEntity Entity =
         InitializedEntity::InitializeParameter(S.Context, ToType,
                                                /*Consumed=*/false);
-    if (S.CanPerformCopyInitialization(Entity, S.Owned(From))) {
+    if (S.CanPerformCopyInitialization(Entity, From)) {
       Result.setUserDefined();
       Result.UserDefined.Before.setAsIdentityConversion();
       // Initializer lists don't have a type.
@@ -4878,13 +4878,13 @@
       PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
     if (FromRes.isInvalid())
       return ExprError();
-    From = FromRes.take();
+    From = FromRes.get();
   }
 
   if (!Context.hasSameType(From->getType(), DestType))
     From = ImpCastExprToType(From, DestType, CK_NoOp,
-                             From->getValueKind()).take();
-  return Owned(From);
+                             From->getValueKind()).get();
+  return From;
 }
 
 /// TryContextuallyConvertToBool - Attempt to contextually convert the
@@ -5166,7 +5166,7 @@
     QualType ConvTy = Conv->getConversionType().getNonReferenceType();
     Converter.noteAmbiguous(SemaRef, Conv, ConvTy);
   }
-  return SemaRef.Owned(From);
+  return From;
 }
 
 static bool
@@ -5299,14 +5299,14 @@
     SourceLocation Loc, Expr *From, ContextualImplicitConverter &Converter) {
   // We can't perform any more checking for type-dependent expressions.
   if (From->isTypeDependent())
-    return Owned(From);
+    return From;
 
   // Process placeholders immediately.
   if (From->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(From);
     if (result.isInvalid())
       return result;
-    From = result.take();
+    From = result.get();
   }
 
   // If the expression already has a matching type, we're golden.
@@ -5322,7 +5322,7 @@
   if (!RecordTy || !getLangOpts().CPlusPlus) {
     if (!Converter.Suppress)
       Converter.diagnoseNoMatch(*this, Loc, T) << From->getSourceRange();
-    return Owned(From);
+    return From;
   }
 
   // We must have a complete class type.
@@ -5339,7 +5339,7 @@
   } IncompleteDiagnoser(Converter, From);
 
   if (RequireCompleteType(Loc, T, IncompleteDiagnoser))
-    return Owned(From);
+    return From;
 
   // Look for a conversion to an integral or enumeration type.
   UnresolvedSet<4>
@@ -5708,7 +5708,7 @@
         InitializationFailed = true;
         break;
       }
-      ConvertedArgs.push_back(R.take());
+      ConvertedArgs.push_back(R.get());
     } else {
       ExprResult R =
         PerformCopyInitialization(InitializedEntity::InitializeParameter(
@@ -5720,7 +5720,7 @@
         InitializationFailed = true;
         break;
       }
-      ConvertedArgs.push_back(R.take());
+      ConvertedArgs.push_back(R.get());
     }
   }
 
@@ -5732,8 +5732,8 @@
     EnableIfAttr *EIA = cast<EnableIfAttr>(*I);
     if (!EIA->getCond()->EvaluateWithSubstitution(
             Result, Context, Function,
-            llvm::ArrayRef<const Expr*>(ConvertedArgs.data(),
-                                        ConvertedArgs.size())) ||
+            ArrayRef<const Expr*>(ConvertedArgs.data(),
+                                  ConvertedArgs.size())) ||
         !Result.isInt() || !Result.getInt().getBoolValue()) {
       return EIA;
     }
@@ -10153,12 +10153,12 @@
 
     // Fix the expression to refer to 'fn'.
     SingleFunctionExpression =
-      Owned(FixOverloadedFunctionReference(SrcExpr.take(), found, fn));
+        FixOverloadedFunctionReference(SrcExpr.get(), found, fn);
 
     // If desired, do function-to-pointer decay.
     if (doFunctionPointerConverion) {
       SingleFunctionExpression =
-        DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.take());
+        DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.get());
       if (SingleFunctionExpression.isInvalid()) {
         SrcExpr = ExprError();
         return true;
@@ -10429,7 +10429,7 @@
 BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
                       UnresolvedLookupExpr *ULE,
                       SourceLocation LParenLoc,
-                      llvm::MutableArrayRef<Expr *> Args,
+                      MutableArrayRef<Expr *> Args,
                       SourceLocation RParenLoc,
                       bool EmptyLookup, bool AllowTypoCorrection) {
   // Do not try to recover if it is already building a recovery call.
@@ -10490,7 +10490,7 @@
   // This shouldn't cause an infinite loop because we're giving it
   // an expression with viable lookup results, which should never
   // end up here.
-  return SemaRef.ActOnCallExpr(/*Scope*/ nullptr, NewFn.take(), LParenLoc,
+  return SemaRef.ActOnCallExpr(/*Scope*/ nullptr, NewFn.get(), LParenLoc,
                                MultiExprArg(Args.data(), Args.size()),
                                RParenLoc);
 }
@@ -10546,7 +10546,7 @@
                                             Context.DependentTy, VK_RValue,
                                             RParenLoc);
       CE->setTypeDependent(true);
-      *Result = Owned(CE);
+      *Result = CE;
       return true;
     }
     return false;
@@ -10713,11 +10713,8 @@
 
   if (Input->isTypeDependent()) {
     if (Fns.empty())
-      return Owned(new (Context) UnaryOperator(Input,
-                                               Opc,
-                                               Context.DependentTy,
-                                               VK_RValue, OK_Ordinary,
-                                               OpLoc));
+      return new (Context) UnaryOperator(Input, Opc, Context.DependentTy,
+                                         VK_RValue, OK_Ordinary, OpLoc);
 
     CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
     UnresolvedLookupExpr *Fn
@@ -10725,10 +10722,9 @@
                                      NestedNameSpecifierLoc(), OpNameInfo,
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
-    return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, ArgsArray,
-                                                   Context.DependentTy,
-                                                   VK_RValue,
-                                                   OpLoc, false));
+    return new (Context)
+        CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy,
+                            VK_RValue, OpLoc, false);
   }
 
   // Build an empty overload set.
@@ -10770,7 +10766,7 @@
                                               Best->FoundDecl, Method);
         if (InputRes.isInvalid())
           return ExprError();
-        Input = InputRes.take();
+        Input = InputRes.get();
       } else {
         // Convert the arguments.
         ExprResult InputInit
@@ -10781,7 +10777,7 @@
                                       Input);
         if (InputInit.isInvalid())
           return ExprError();
-        Input = InputInit.take();
+        Input = InputInit.get();
       }
 
       // Build the actual expression node.
@@ -10797,7 +10793,7 @@
 
       Args[0] = Input;
       CallExpr *TheCall =
-        new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), ArgsArray,
+        new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray,
                                           ResultTy, VK, OpLoc, false);
 
       if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
@@ -10813,7 +10809,7 @@
                                   Best->Conversions[0], AA_Passing);
       if (InputRes.isInvalid())
         return ExprError();
-      Input = InputRes.take();
+      Input = InputRes.get();
       break;
     }
   }
@@ -10892,20 +10888,14 @@
       // If there are no functions to store, just build a dependent
       // BinaryOperator or CompoundAssignment.
       if (Opc <= BO_Assign || Opc > BO_OrAssign)
-        return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
-                                                  Context.DependentTy,
-                                                  VK_RValue, OK_Ordinary,
-                                                  OpLoc,
-                                                  FPFeatures.fp_contract));
+        return new (Context) BinaryOperator(
+            Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary,
+            OpLoc, FPFeatures.fp_contract);
 
-      return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc,
-                                                        Context.DependentTy,
-                                                        VK_LValue,
-                                                        OK_Ordinary,
-                                                        Context.DependentTy,
-                                                        Context.DependentTy,
-                                                        OpLoc,
-                                                        FPFeatures.fp_contract));
+      return new (Context) CompoundAssignOperator(
+          Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary,
+          Context.DependentTy, Context.DependentTy, OpLoc,
+          FPFeatures.fp_contract);
     }
 
     // FIXME: save results of ADL from here?
@@ -10917,9 +10907,9 @@
                                      NestedNameSpecifierLoc(), OpNameInfo, 
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
-    return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args,
-                                                Context.DependentTy, VK_RValue,
-                                                OpLoc, FPFeatures.fp_contract));
+    return new (Context)
+        CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy,
+                            VK_RValue, OpLoc, FPFeatures.fp_contract);
   }
 
   // Always do placeholder-like conversions on the RHS.
@@ -10985,7 +10975,7 @@
             PerformCopyInitialization(
               InitializedEntity::InitializeParameter(Context,
                                                      FnDecl->getParamDecl(0)),
-              SourceLocation(), Owned(Args[1]));
+              SourceLocation(), Args[1]);
           if (Arg1.isInvalid())
             return ExprError();
 
@@ -10994,14 +10984,14 @@
                                                 Best->FoundDecl, Method);
           if (Arg0.isInvalid())
             return ExprError();
-          Args[0] = Arg0.takeAs<Expr>();
-          Args[1] = RHS = Arg1.takeAs<Expr>();
+          Args[0] = Arg0.getAs<Expr>();
+          Args[1] = RHS = Arg1.getAs<Expr>();
         } else {
           // Convert the arguments.
           ExprResult Arg0 = PerformCopyInitialization(
             InitializedEntity::InitializeParameter(Context,
                                                    FnDecl->getParamDecl(0)),
-            SourceLocation(), Owned(Args[0]));
+            SourceLocation(), Args[0]);
           if (Arg0.isInvalid())
             return ExprError();
 
@@ -11009,11 +10999,11 @@
             PerformCopyInitialization(
               InitializedEntity::InitializeParameter(Context,
                                                      FnDecl->getParamDecl(1)),
-              SourceLocation(), Owned(Args[1]));
+              SourceLocation(), Args[1]);
           if (Arg1.isInvalid())
             return ExprError();
-          Args[0] = LHS = Arg0.takeAs<Expr>();
-          Args[1] = RHS = Arg1.takeAs<Expr>();
+          Args[0] = LHS = Arg0.getAs<Expr>();
+          Args[1] = RHS = Arg1.getAs<Expr>();
         }
 
         // Build the actual expression node.
@@ -11029,7 +11019,7 @@
         ResultTy = ResultTy.getNonLValueExprType(Context);
 
         CXXOperatorCallExpr *TheCall =
-          new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
+          new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(),
                                             Args, ResultTy, VK, OpLoc,
                                             FPFeatures.fp_contract);
 
@@ -11054,14 +11044,14 @@
                                     Best->Conversions[0], AA_Passing);
         if (ArgsRes0.isInvalid())
           return ExprError();
-        Args[0] = ArgsRes0.take();
+        Args[0] = ArgsRes0.get();
 
         ExprResult ArgsRes1 =
           PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
                                     Best->Conversions[1], AA_Passing);
         if (ArgsRes1.isInvalid())
           return ExprError();
-        Args[1] = ArgsRes1.take();
+        Args[1] = ArgsRes1.get();
         break;
       }
     }
@@ -11168,11 +11158,9 @@
                                      UnresolvedSetIterator());
     // Can't add any actual overloads yet
 
-    return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn,
-                                                   Args,
-                                                   Context.DependentTy,
-                                                   VK_RValue,
-                                                   RLoc, false));
+    return new (Context)
+        CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args,
+                            Context.DependentTy, VK_RValue, RLoc, false);
   }
 
   // Handle placeholders on both operands.
@@ -11214,7 +11202,7 @@
                                               Best->FoundDecl, Method);
         if (Arg0.isInvalid())
           return ExprError();
-        Args[0] = Arg0.take();
+        Args[0] = Arg0.get();
 
         // Convert the arguments.
         ExprResult InputInit
@@ -11222,11 +11210,11 @@
                                                       Context,
                                                       FnDecl->getParamDecl(0)),
                                       SourceLocation(),
-                                      Owned(Args[1]));
+                                      Args[1]);
         if (InputInit.isInvalid())
           return ExprError();
 
-        Args[1] = InputInit.takeAs<Expr>();
+        Args[1] = InputInit.getAs<Expr>();
 
         // Build the actual expression node.
         DeclarationNameInfo OpLocInfo(OpName, LLoc);
@@ -11246,7 +11234,7 @@
 
         CXXOperatorCallExpr *TheCall =
           new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
-                                            FnExpr.take(), Args,
+                                            FnExpr.get(), Args,
                                             ResultTy, VK, RLoc,
                                             false);
 
@@ -11263,14 +11251,14 @@
                                     Best->Conversions[0], AA_Passing);
         if (ArgsRes0.isInvalid())
           return ExprError();
-        Args[0] = ArgsRes0.take();
+        Args[0] = ArgsRes0.get();
 
         ExprResult ArgsRes1 =
           PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
                                     Best->Conversions[1], AA_Passing);
         if (ArgsRes1.isInvalid())
           return ExprError();
-        Args[1] = ArgsRes1.take();
+        Args[1] = ArgsRes1.get();
 
         break;
       }
@@ -11531,7 +11519,7 @@
                                           FoundDecl, Method);
     if (ObjectArg.isInvalid())
       return ExprError();
-    MemExpr->setBase(ObjectArg.take());
+    MemExpr->setBase(ObjectArg.get());
   }
 
   // Convert the rest of the arguments
@@ -11574,7 +11562,7 @@
                                    SourceLocation RParenLoc) {
   if (checkPlaceholderForOverload(*this, Obj))
     return ExprError();
-  ExprResult Object = Owned(Obj);
+  ExprResult Object = Obj;
 
   UnbridgedCastsSet UnbridgedCasts;
   if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts))
@@ -11728,9 +11716,9 @@
     if (Call.isInvalid())
       return ExprError();
     // Record usage of conversion in an implicit cast.
-    Call = Owned(ImplicitCastExpr::Create(Context, Call.get()->getType(),
-                                          CK_UserDefinedConversion,
-                                          Call.get(), nullptr, VK_RValue));
+    Call = ImplicitCastExpr::Create(Context, Call.get()->getType(),
+                                    CK_UserDefinedConversion, Call.get(),
+                                    nullptr, VK_RValue);
 
     return ActOnCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc);
   }
@@ -11774,7 +11762,7 @@
   ResultTy = ResultTy.getNonLValueExprType(Context);
 
   CXXOperatorCallExpr *TheCall = new (Context)
-      CXXOperatorCallExpr(Context, OO_Call, NewFn.take(),
+      CXXOperatorCallExpr(Context, OO_Call, NewFn.get(),
                           llvm::makeArrayRef(MethodArgs.get(), Args.size() + 1),
                           ResultTy, VK, RParenLoc, false);
   MethodArgs.reset();
@@ -11797,7 +11785,7 @@
     IsError = true;
   else
     Object = ObjRes;
-  TheCall->setArg(0, Object.take());
+  TheCall->setArg(0, Object.get());
 
   // Check the argument types.
   for (unsigned i = 0; i != NumParams; i++) {
@@ -11814,7 +11802,7 @@
                                     SourceLocation(), Arg);
 
       IsError |= InputInit.isInvalid();
-      Arg = InputInit.takeAs<Expr>();
+      Arg = InputInit.getAs<Expr>();
     } else {
       ExprResult DefArg
         = BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i));
@@ -11823,7 +11811,7 @@
         break;
       }
 
-      Arg = DefArg.takeAs<Expr>();
+      Arg = DefArg.getAs<Expr>();
     }
 
     TheCall->setArg(i + 1, Arg);
@@ -11836,7 +11824,7 @@
       ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod,
                                                         nullptr);
       IsError |= Arg.isInvalid();
-      TheCall->setArg(i + 1, Arg.take());
+      TheCall->setArg(i + 1, Arg.get());
     }
   }
 
@@ -11944,7 +11932,7 @@
                                         Best->FoundDecl, Method);
   if (BaseResult.isInvalid())
     return ExprError();
-  Base = BaseResult.take();
+  Base = BaseResult.get();
 
   // Build the operator call.
   ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, Best->FoundDecl,
@@ -11956,7 +11944,7 @@
   ExprValueKind VK = Expr::getValueKindForType(ResultTy);
   ResultTy = ResultTy.getNonLValueExprType(Context);
   CXXOperatorCallExpr *TheCall =
-    new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.take(),
+    new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.get(),
                                       Base, ResultTy, VK, OpLoc, false);
 
   if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
@@ -12018,7 +12006,7 @@
       SourceLocation(), Args[ArgIdx]);
     if (InputInit.isInvalid())
       return true;
-    ConvArgs[ArgIdx] = InputInit.take();
+    ConvArgs[ArgIdx] = InputInit.get();
   }
 
   QualType ResultTy = FD->getReturnType();
@@ -12026,7 +12014,7 @@
   ResultTy = ResultTy.getNonLValueExprType(Context);
 
   UserDefinedLiteral *UDL =
-    new (Context) UserDefinedLiteral(Context, Fn.take(),
+    new (Context) UserDefinedLiteral(Context, Fn.get(),
                                      llvm::makeArrayRef(ConvArgs, Args.size()),
                                      ResultTy, VK, LitEndLoc, UDSuffixLoc);
 
@@ -12282,7 +12270,7 @@
 ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,
                                                 DeclAccessPair Found,
                                                 FunctionDecl *Fn) {
-  return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn));
+  return FixOverloadedFunctionReference(E.get(), Found, Fn);
 }
 
 } // end namespace clang
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index 94b1943..c8d34f8 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -284,6 +284,7 @@
     bool tryBuildGetOfReference(Expr *op, ExprResult &result);
     bool findSetter(bool warn=true);
     bool findGetter();
+    bool DiagnoseUnsupportedPropertyUse();
 
     Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
     ExprResult buildGet() override;
@@ -393,7 +394,7 @@
 
   ExprResult getExpr = buildGet();
   if (getExpr.isInvalid()) return ExprError();
-  addResultSemanticExpr(getExpr.take());
+  addResultSemanticExpr(getExpr.get());
 
   return complete(syntacticBase);
 }
@@ -426,7 +427,7 @@
     BinaryOperatorKind nonCompound =
       BinaryOperator::getOpForCompoundAssignment(opcode);
     result = S.BuildBinOp(Sc, opcLoc, nonCompound,
-                          opLHS.take(), capturedRHS);
+                          opLHS.get(), capturedRHS);
     if (result.isInvalid()) return ExprError();
 
     syntactic =
@@ -441,9 +442,9 @@
 
   // The result of the assignment, if not void, is the value set into
   // the l-value.
-  result = buildSet(result.take(), opcLoc, /*captureSetValueAsResult*/ true);
+  result = buildSet(result.get(), opcLoc, /*captureSetValueAsResult*/ true);
   if (result.isInvalid()) return ExprError();
-  addSemanticExpr(result.take());
+  addSemanticExpr(result.get());
 
   return complete(syntactic);
 }
@@ -467,7 +468,7 @@
   // That's the postfix result.
   if (UnaryOperator::isPostfix(opcode) &&
       (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) {
-    result = capture(result.take());
+    result = capture(result.get());
     setResultToLastSemantic();
   }
 
@@ -477,17 +478,17 @@
                                      GenericLoc);
 
   if (UnaryOperator::isIncrementOp(opcode)) {
-    result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.take(), one);
+    result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one);
   } else {
-    result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.take(), one);
+    result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one);
   }
   if (result.isInvalid()) return ExprError();
 
   // Store that back into the result.  The value stored is the result
   // of a prefix operation.
-  result = buildSet(result.take(), opcLoc, UnaryOperator::isPrefix(opcode));
+  result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode));
   if (result.isInvalid()) return ExprError();
-  addSemanticExpr(result.take());
+  addSemanticExpr(result.get());
 
   UnaryOperator *syntactic =
     new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
@@ -541,7 +542,7 @@
   if (RefExpr->isExplicitProperty()) {
     const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
     if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
-      return true;
+      return !Prop->hasAttr<IBOutletAttr>();
 
     T = Prop->getType();
   } else if (Getter) {
@@ -568,13 +569,11 @@
       assert(setter && "both setter and getter are null - cannot happen");
       IdentifierInfo *setterName = 
         setter->getSelector().getIdentifierInfoForSlot(0);
-      const char *compStr = setterName->getNameStart();
-      compStr += 3;
-      IdentifierInfo *getterName = &S.Context.Idents.get(compStr);
+      IdentifierInfo *getterName =
+          &S.Context.Idents.get(setterName->getName().substr(3));
       GetterSelector = 
         S.PP.getSelectorTable().getNullarySelector(getterName);
       return false;
-
     }
   }
 
@@ -643,6 +642,20 @@
   return false;
 }
 
+bool ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
+  if (S.getCurLexicalContext()->isObjCContainer() &&
+      S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
+      S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) {
+    if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) {
+        S.Diag(RefExpr->getLocation(),
+               diag::err_property_function_in_objc_container);
+        S.Diag(prop->getLocation(), diag::note_property_declare);
+        return true;
+    }
+  }
+  return false;
+}
+
 /// Capture the base object of an Objective-C property expression.
 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
   assert(InstanceReceiver == nullptr);
@@ -666,6 +679,9 @@
 /// Load from an Objective-C property reference.
 ExprResult ObjCPropertyOpBuilder::buildGet() {
   findGetter();
+  if (!Getter && DiagnoseUnsupportedPropertyUse())
+      return ExprError();
+
   assert(Getter);
 
   if (SyntacticRefExpr)
@@ -680,7 +696,8 @@
     assert(InstanceReceiver);
     receiverType = InstanceReceiver->getType();
   }
-
+  if (!Getter->isImplicit())
+    S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true);
   // Build a message-send.
   ExprResult msg;
   if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
@@ -704,6 +721,8 @@
 ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
                                            bool captureSetValueAsResult) {
   bool hasSetter = findSetter(false);
+  if (!hasSetter && DiagnoseUnsupportedPropertyUse())
+      return ExprError();
   assert(hasSetter); (void) hasSetter;
 
   if (SyntacticRefExpr)
@@ -733,7 +752,7 @@
                                      Sema::AA_Assigning))
         return ExprError();
 
-      op = opResult.take();
+      op = opResult.get();
       assert(op && "successful assignment left argument invalid?");
     }
     else if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(op)) {
@@ -753,6 +772,8 @@
 
   // Build a message-send.
   ExprResult msg;
+  if (!Setter->isImplicit())
+    S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true);
   if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
       RefExpr->isObjectReceiver()) {
     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
@@ -795,13 +816,20 @@
 
   // As a special case, if the method returns 'id', try to get
   // a better type from the property.
-  if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
-      result.get()->getType()->isObjCIdType()) {
+  if (RefExpr->isExplicitProperty() && result.get()->isRValue()) {
     QualType propType = RefExpr->getExplicitProperty()->getType();
-    if (const ObjCObjectPointerType *ptr
-          = propType->getAs<ObjCObjectPointerType>()) {
-      if (!ptr->isObjCIdType())
-        result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+    if (result.get()->getType()->isObjCIdType()) {
+      if (const ObjCObjectPointerType *ptr
+            = propType->getAs<ObjCObjectPointerType>()) {
+        if (!ptr->isObjCIdType())
+          result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+      }
+    }
+    if (S.getLangOpts().ObjCAutoRefCount) {
+      Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
+      if (LT == Qualifiers::OCL_Weak)
+        if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
+              S.getCurFunction()->markSafeWeakUse(RefExpr);
     }
   }
 
@@ -841,7 +869,7 @@
     ExprResult result;
     if (tryBuildGetOfReference(LHS, result)) {
       if (result.isInvalid()) return ExprError();
-      return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
+      return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS);
     }
 
     // Otherwise, it's an error.
@@ -885,7 +913,7 @@
     ExprResult result;
     if (tryBuildGetOfReference(op, result)) {
       if (result.isInvalid()) return ExprError();
-      return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
+      return S.BuildUnaryOp(Sc, opcLoc, opcode, result.get());
     }
 
     // Otherwise, it's an error.
@@ -913,14 +941,11 @@
 }
 
 ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
-  if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty()) {
-    DiagnosticsEngine::Level Level =
-      S.Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                 SyntacticForm->getLocStart());
-    if (Level != DiagnosticsEngine::Ignored)
+  if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
+      !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+                         SyntacticForm->getLocStart()))
       S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
                                  SyntacticRefExpr->isMessagingGetter());
-  }
 
   return PseudoOpBuilder::complete(SyntacticForm);
 }
@@ -1074,7 +1099,7 @@
                                                       true /*instance*/);
   if (!Getter)
     return;
-  QualType T = Getter->param_begin()[0]->getType();
+  QualType T = Getter->parameters()[0]->getType();
   S.CheckObjCARCConversion(Key->getSourceRange(), 
                          T, Key, Sema::CCK_ImplicitConversion);
 }
@@ -1167,13 +1192,13 @@
   }
   
   if (AtIndexGetter) {
-    QualType T = AtIndexGetter->param_begin()[0]->getType();
+    QualType T = AtIndexGetter->parameters()[0]->getType();
     if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
         (!arrayRef && !T->isObjCObjectPointerType())) {
       S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 
              arrayRef ? diag::err_objc_subscript_index_type
                       : diag::err_objc_subscript_key_type) << T;
-      S.Diag(AtIndexGetter->param_begin()[0]->getLocation(), 
+      S.Diag(AtIndexGetter->parameters()[0]->getLocation(), 
              diag::note_parameter_type) << T;
       return false;
     }
@@ -1290,26 +1315,26 @@
   
   bool err = false;
   if (AtIndexSetter && arrayRef) {
-    QualType T = AtIndexSetter->param_begin()[1]->getType();
+    QualType T = AtIndexSetter->parameters()[1]->getType();
     if (!T->isIntegralOrEnumerationType()) {
       S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 
              diag::err_objc_subscript_index_type) << T;
-      S.Diag(AtIndexSetter->param_begin()[1]->getLocation(), 
+      S.Diag(AtIndexSetter->parameters()[1]->getLocation(), 
              diag::note_parameter_type) << T;
       err = true;
     }
-    T = AtIndexSetter->param_begin()[0]->getType();
+    T = AtIndexSetter->parameters()[0]->getType();
     if (!T->isObjCObjectPointerType()) {
       S.Diag(RefExpr->getBaseExpr()->getExprLoc(), 
              diag::err_objc_subscript_object_type) << T << arrayRef;
-      S.Diag(AtIndexSetter->param_begin()[0]->getLocation(), 
+      S.Diag(AtIndexSetter->parameters()[0]->getLocation(), 
              diag::note_parameter_type) << T;
       err = true;
     }
   }
   else if (AtIndexSetter && !arrayRef)
     for (unsigned i=0; i <2; i++) {
-      QualType T = AtIndexSetter->param_begin()[i]->getType();
+      QualType T = AtIndexSetter->parameters()[i]->getType();
       if (!T->isObjCObjectPointerType()) {
         if (i == 1)
           S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
@@ -1317,7 +1342,7 @@
         else
           S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
                  diag::err_objc_subscript_dic_object_type) << T;
-        S.Diag(AtIndexSetter->param_begin()[i]->getLocation(), 
+        S.Diag(AtIndexSetter->parameters()[i]->getLocation(), 
                diag::note_parameter_type) << T;
         err = true;
       }
@@ -1341,6 +1366,8 @@
   // Arguments.
   Expr *args[] = { Index };
   assert(InstanceBase);
+  if (AtIndexGetter)
+    S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc);
   msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
                                        GenericLoc,
                                        AtIndexGetterSelector, AtIndexGetter,
@@ -1357,7 +1384,8 @@
                                            bool captureSetValueAsResult) {
   if (!findAtIndexSetter())
     return ExprError();
-  
+  if (AtIndexSetter)
+    S.DiagnoseUseOfDecl(AtIndexSetter, GenericLoc);
   QualType receiverType = InstanceBase->getType();
   Expr *Index = InstanceKey;
   
@@ -1419,7 +1447,7 @@
   }
 
   MultiExprArg ArgExprs;
-  return S.ActOnCallExpr(S.getCurScope(), GetterExpr.take(),
+  return S.ActOnCallExpr(S.getCurScope(), GetterExpr.get(),
                          RefExpr->getSourceRange().getBegin(), ArgExprs,
                          RefExpr->getSourceRange().getEnd());
 }
@@ -1450,7 +1478,7 @@
 
   SmallVector<Expr*, 1> ArgExprs;
   ArgExprs.push_back(op);
-  return S.ActOnCallExpr(S.getCurScope(), SetterExpr.take(),
+  return S.ActOnCallExpr(S.getCurScope(), SetterExpr.get(),
                          RefExpr->getSourceRange().getBegin(), ArgExprs,
                          op->getSourceRange().getEnd());
 }
@@ -1517,7 +1545,7 @@
   if (RHS->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(RHS);
     if (result.isInvalid()) return ExprError();
-    RHS = result.take();
+    RHS = result.get();
   }
 
   Expr *opaqueRef = LHS->IgnoreParens();
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 7d568ee..dc5619d 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -49,7 +49,7 @@
   // operand, even incomplete types.
 
   // Same thing in for stmt first clause (when expr) and third clause.
-  return Owned(static_cast<Stmt*>(FE.take()));
+  return StmtResult(FE.getAs<Stmt>());
 }
 
 
@@ -60,7 +60,7 @@
 
 StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc,
                                bool HasLeadingEmptyMacro) {
-  return Owned(new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro));
+  return new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro);
 }
 
 StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
@@ -70,7 +70,7 @@
   // If we have an invalid decl, just return an error.
   if (DG.isNull()) return StmtError();
 
-  return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
+  return new (Context) DeclStmt(DG, StartLoc, EndLoc);
 }
 
 void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
@@ -344,7 +344,7 @@
       DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
   }
 
-  return Owned(new (Context) CompoundStmt(Context, Elts, L, R));
+  return new (Context) CompoundStmt(Context, Elts, L, R);
 }
 
 StmtResult
@@ -362,7 +362,7 @@
     // C99 6.8.4.2p3: The expression shall be an integer constant.
     // However, GCC allows any evaluatable integer expression.
     if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent()) {
-      LHSVal = VerifyIntegerConstantExpression(LHSVal).take();
+      LHSVal = VerifyIntegerConstantExpression(LHSVal).get();
       if (!LHSVal)
         return StmtError();
     }
@@ -370,21 +370,21 @@
     // GCC extension: The expression shall be an integer constant.
 
     if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent()) {
-      RHSVal = VerifyIntegerConstantExpression(RHSVal).take();
+      RHSVal = VerifyIntegerConstantExpression(RHSVal).get();
       // Recover from an error by just forgetting about it.
     }
   }
 
   LHSVal = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,
-                               getLangOpts().CPlusPlus11).take();
+                               getLangOpts().CPlusPlus11).get();
   if (RHSVal)
     RHSVal = ActOnFinishFullExpr(RHSVal, RHSVal->getExprLoc(), false,
-                                 getLangOpts().CPlusPlus11).take();
+                                 getLangOpts().CPlusPlus11).get();
 
   CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
                                         ColonLoc);
   getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
-  return Owned(CS);
+  return CS;
 }
 
 /// ActOnCaseStmtBody - This installs a statement as the body of a case.
@@ -402,12 +402,12 @@
 
   if (getCurFunction()->SwitchStack.empty()) {
     Diag(DefaultLoc, diag::err_default_not_in_switch);
-    return Owned(SubStmt);
+    return SubStmt;
   }
 
   DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
   getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
-  return Owned(DS);
+  return DS;
 }
 
 StmtResult
@@ -417,7 +417,7 @@
   if (TheDecl->getStmt()) {
     Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();
     Diag(TheDecl->getLocation(), diag::note_previous_definition);
-    return Owned(SubStmt);
+    return SubStmt;
   }
 
   // Otherwise, things are good.  Fill in the declaration and return it.
@@ -427,7 +427,7 @@
     TheDecl->setLocStart(IdentLoc);
     TheDecl->setLocation(IdentLoc);
   }
-  return Owned(LS);
+  return LS;
 }
 
 StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc,
@@ -435,7 +435,7 @@
                                      Stmt *SubStmt) {
   // Fill in the declaration and return it.
   AttributedStmt *LS = AttributedStmt::Create(Context, AttrLoc, Attrs, SubStmt);
-  return Owned(LS);
+  return LS;
 }
 
 StmtResult
@@ -458,7 +458,7 @@
     if (CondResult.isInvalid())
       return StmtError();
   }
-  Expr *ConditionExpr = CondResult.takeAs<Expr>();
+  Expr *ConditionExpr = CondResult.getAs<Expr>();
   if (!ConditionExpr)
     return StmtError();
 
@@ -471,8 +471,8 @@
 
   DiagnoseUnusedExprResult(elseStmt);
 
-  return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
-                                    thenStmt, ElseLoc, elseStmt));
+  return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
+                              thenStmt, ElseLoc, elseStmt);
 }
 
 /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
@@ -587,7 +587,7 @@
     if (CondResult.isInvalid())
       return StmtError();
 
-    Cond = CondResult.release();
+    Cond = CondResult.get();
   }
 
   if (!Cond)
@@ -643,25 +643,25 @@
   CondResult =
       PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);
   if (CondResult.isInvalid()) return StmtError();
-  Cond = CondResult.take();
+  Cond = CondResult.get();
 
   // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
   CondResult = UsualUnaryConversions(Cond);
   if (CondResult.isInvalid()) return StmtError();
-  Cond = CondResult.take();
+  Cond = CondResult.get();
 
   if (!CondVar) {
     CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
     if (CondResult.isInvalid())
       return StmtError();
-    Cond = CondResult.take();
+    Cond = CondResult.get();
   }
 
   getCurFunction()->setHasBranchIntoScope();
 
   SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
   getCurFunction()->SwitchStack.push_back(SS);
-  return Owned(SS);
+  return SS;
 }
 
 static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {
@@ -798,7 +798,7 @@
           CaseListIsErroneous = true;
           continue;
         }
-        Lo = ConvLo.take();
+        Lo = ConvLo.get();
       } else {
         // We already verified that the expression has a i-c-e value (C99
         // 6.8.4.2p3) - get that value now.
@@ -806,8 +806,8 @@
 
         // If the LHS is not the same type as the condition, insert an implicit
         // cast.
-        Lo = DefaultLvalueConversion(Lo).take();
-        Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).take();
+        Lo = DefaultLvalueConversion(Lo).get();
+        Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).get();
       }
 
       // Convert the value to the same width/sign as the condition had prior to
@@ -919,14 +919,14 @@
             CaseListIsErroneous = true;
             continue;
           }
-          Hi = ConvHi.take();
+          Hi = ConvHi.get();
         } else {
           HiVal = Hi->EvaluateKnownConstInt(Context);
 
           // If the RHS is not the same type as the condition, insert an
           // implicit cast.
-          Hi = DefaultLvalueConversion(Hi).take();
-          Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).take();
+          Hi = DefaultLvalueConversion(Hi).get();
+          Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).get();
         }
 
         // Convert the value to the same width/sign as the condition.
@@ -1151,15 +1151,13 @@
   if (CaseListIsErroneous)
     return StmtError();
 
-  return Owned(SS);
+  return SS;
 }
 
 void
 Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
                              Expr *SrcExpr) {
-  if (Diags.getDiagnosticLevel(diag::warn_not_in_enum_assignment,
-                               SrcExpr->getExprLoc()) ==
-      DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc()))
     return;
 
   if (const EnumType *ET = DstType->getAs<EnumType>())
@@ -1215,7 +1213,7 @@
     if (CondResult.isInvalid())
       return StmtError();
   }
-  Expr *ConditionExpr = CondResult.take();
+  Expr *ConditionExpr = CondResult.get();
   if (!ConditionExpr)
     return StmtError();
   CheckBreakContinueBinding(ConditionExpr);
@@ -1225,8 +1223,8 @@
   if (isa<NullStmt>(Body))
     getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
-                                       Body, WhileLoc));
+  return new (Context)
+      WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);
 }
 
 StmtResult
@@ -1239,16 +1237,16 @@
   ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);
   if (CondResult.isInvalid())
     return StmtError();
-  Cond = CondResult.take();
+  Cond = CondResult.get();
 
   CondResult = ActOnFinishFullExpr(Cond, DoLoc);
   if (CondResult.isInvalid())
     return StmtError();
-  Cond = CondResult.take();
+  Cond = CondResult.get();
 
   DiagnoseUnusedExprResult(Body);
 
-  return Owned(new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen));
+  return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
 }
 
 namespace {
@@ -1406,9 +1404,8 @@
     // Condition is empty
     if (!Second) return;
 
-    if (S.Diags.getDiagnosticLevel(diag::warn_variables_not_in_loop_body,
-                                   Second->getLocStart())
-        == DiagnosticsEngine::Ignored)
+    if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body,
+                          Second->getLocStart()))
       return;
 
     PartialDiagnostic PDiag = S.PDiag(diag::warn_variables_not_in_loop_body);
@@ -1535,9 +1532,8 @@
     // Return when there is nothing to check.
     if (!Body || !Third) return;
 
-    if (S.Diags.getDiagnosticLevel(diag::warn_redundant_loop_iteration,
-                                   Third->getLocStart())
-        == DiagnosticsEngine::Ignored)
+    if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration,
+                          Third->getLocStart()))
       return;
 
     // Get the last statement from the loop body.
@@ -1623,7 +1619,7 @@
       return StmtError();
   }
 
-  Expr *Third  = third.release().takeAs<Expr>();
+  Expr *Third  = third.release().getAs<Expr>();
 
   DiagnoseUnusedExprResult(First);
   DiagnoseUnusedExprResult(Third);
@@ -1632,10 +1628,8 @@
   if (isa<NullStmt>(Body))
     getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return Owned(new (Context) ForStmt(Context, First,
-                                     SecondResult.take(), ConditionVar,
-                                     Third, Body, ForLoc, LParenLoc,
-                                     RParenLoc));
+  return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,
+                               Third, Body, ForLoc, LParenLoc, RParenLoc);
 }
 
 /// In an Objective C collection iteration statement:
@@ -1647,12 +1641,12 @@
   // use of pseudo-object l-values in this position.
   ExprResult result = CheckPlaceholderExpr(E);
   if (result.isInvalid()) return StmtError();
-  E = result.take();
+  E = result.get();
 
   ExprResult FullExpr = ActOnFinishFullExpr(E);
   if (FullExpr.isInvalid())
     return StmtError();
-  return StmtResult(static_cast<Stmt*>(FullExpr.take()));
+  return StmtResult(static_cast<Stmt*>(FullExpr.get()));
 }
 
 ExprResult
@@ -1661,13 +1655,13 @@
     return ExprError();
 
   // Bail out early if we've got a type-dependent expression.
-  if (collection->isTypeDependent()) return Owned(collection);
+  if (collection->isTypeDependent()) return collection;
 
   // Perform normal l-value conversion.
   ExprResult result = DefaultFunctionArrayLvalueConversion(collection);
   if (result.isInvalid())
     return ExprError();
-  collection = result.take();
+  collection = result.get();
 
   // The operand needs to have object-pointer type.
   // TODO: should we do a contextual conversion?
@@ -1723,7 +1717,7 @@
   }
 
   // Wrap up any cleanups in the expression.
-  return Owned(collection);
+  return collection;
 }
 
 StmtResult
@@ -1798,13 +1792,12 @@
   if (CollectionExprResult.isInvalid())
     return StmtError();
 
-  CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.take());
+  CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
   if (CollectionExprResult.isInvalid())
     return StmtError();
 
-  return Owned(new (Context) ObjCForCollectionStmt(First,
-                                                   CollectionExprResult.take(),
-                                                   nullptr, ForLoc, RParenLoc));
+  return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(),
+                                             nullptr, ForLoc, RParenLoc);
 }
 
 /// Finish building a variable declaration for a for-range statement.
@@ -1941,7 +1934,7 @@
 
   // Claim the type doesn't contain auto: we've already done the checking.
   DeclGroupPtrTy RangeGroup =
-      BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
+      BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
                            /*TypeMayContainAuto=*/ false);
   StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc);
   if (RangeDecl.isInvalid()) {
@@ -2173,9 +2166,8 @@
       // Find the array bound.
       ExprResult BoundExpr;
       if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(UnqAT))
-        BoundExpr = Owned(IntegerLiteral::Create(Context, CAT->getSize(),
-                                                 Context.getPointerDiffType(),
-                                                 RangeLoc));
+        BoundExpr = IntegerLiteral::Create(
+            Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);
       else if (const VariableArrayType *VAT =
                dyn_cast<VariableArrayType>(UnqAT))
         BoundExpr = VAT->getSizeExpr();
@@ -2259,7 +2251,7 @@
     Decl *BeginEndDecls[] = { BeginVar, EndVar };
     // Claim the type doesn't contain auto: we've already done the checking.
     DeclGroupPtrTy BeginEndGroup =
-        BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *>(BeginEndDecls, 2),
+        BuildDeclaratorGroup(MutableArrayRef<Decl *>(BeginEndDecls, 2),
                              /*TypeMayContainAuto=*/ false);
     BeginEndDecl = ActOnDeclStmt(BeginEndGroup, ColonLoc, ColonLoc);
 
@@ -2332,11 +2324,9 @@
   if (Kind == BFRK_Check)
     return StmtResult();
 
-  return Owned(new (Context) CXXForRangeStmt(RangeDS,
-                                     cast_or_null<DeclStmt>(BeginEndDecl.get()),
-                                             NotEqExpr.take(), IncrExpr.take(),
-                                             LoopVarDS, /*Body=*/nullptr,
-                                             ForLoc, ColonLoc, RParenLoc));
+  return new (Context) CXXForRangeStmt(
+      RangeDS, cast_or_null<DeclStmt>(BeginEndDecl.get()), NotEqExpr.get(),
+      IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, ColonLoc, RParenLoc);
 }
 
 /// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach
@@ -2375,7 +2365,7 @@
                                LabelDecl *TheDecl) {
   getCurFunction()->setHasBranchIntoScope();
   TheDecl->markUsed(Context);
-  return Owned(new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc));
+  return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
 }
 
 StmtResult
@@ -2385,12 +2375,12 @@
   if (!E->isTypeDependent()) {
     QualType ETy = E->getType();
     QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
-    ExprResult ExprRes = Owned(E);
+    ExprResult ExprRes = E;
     AssignConvertType ConvTy =
       CheckSingleAssignmentConstraints(DestTy, ExprRes);
     if (ExprRes.isInvalid())
       return StmtError();
-    E = ExprRes.take();
+    E = ExprRes.get();
     if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
       return StmtError();
   }
@@ -2398,11 +2388,11 @@
   ExprResult ExprRes = ActOnFinishFullExpr(E);
   if (ExprRes.isInvalid())
     return StmtError();
-  E = ExprRes.take();
+  E = ExprRes.get();
 
   getCurFunction()->setHasIndirectGoto();
 
-  return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
+  return new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E);
 }
 
 StmtResult
@@ -2413,7 +2403,7 @@
     return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
   }
 
-  return Owned(new (Context) ContinueStmt(ContinueLoc));
+  return new (Context) ContinueStmt(ContinueLoc);
 }
 
 StmtResult
@@ -2423,8 +2413,11 @@
     // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
     return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
   }
+  if (S->isOpenMPLoopScope())
+    return StmtError(Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
+                     << "break");
 
-  return Owned(new (Context) BreakStmt(BreakLoc));
+  return new (Context) BreakStmt(BreakLoc);
 }
 
 /// \brief Determine whether the given expression is a candidate for
@@ -2620,7 +2613,7 @@
       ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
       if (Result.isInvalid())
         return StmtError();
-      RetValExp = Result.take();
+      RetValExp = Result.get();
 
       if (!CurContext->isDependentContext())
         FnRetType = RetValExp->getType();
@@ -2704,7 +2697,7 @@
       // FIXME: Cleanup temporaries here, anyway?
       return StmtError();
     }
-    RetValExp = Res.take();
+    RetValExp = Res.get();
     CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
   } else {
     NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
@@ -2714,7 +2707,7 @@
     ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
     if (ER.isInvalid())
       return StmtError();
-    RetValExp = ER.take();
+    RetValExp = ER.get();
   }
   ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp,
                                                 NRVOCandidate);
@@ -2725,7 +2718,7 @@
   if (CurCap->HasImplicitReturnType || NRVOCandidate)
     FunctionScopes.back()->Returns.push_back(Result);
 
-  return Owned(Result);
+  return Result;
 }
 
 /// Deduce the return type for a function from a returned expression, per
@@ -2921,13 +2914,13 @@
             D = diag::ext_return_has_void_expr;
         }
         else {
-          ExprResult Result = Owned(RetValExp);
-          Result = IgnoredValueConversions(Result.take());
+          ExprResult Result = RetValExp;
+          Result = IgnoredValueConversions(Result.get());
           if (Result.isInvalid())
             return StmtError();
-          RetValExp = Result.take();
+          RetValExp = Result.get();
           RetValExp = ImpCastExprToType(RetValExp,
-                                        Context.VoidTy, CK_ToVoid).take();
+                                        Context.VoidTy, CK_ToVoid).get();
         }
         // return of void in constructor/destructor is illegal in C++.
         if (D == diag::err_ctor_dtor_returns_void) {
@@ -2959,7 +2952,7 @@
         ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
         if (ER.isInvalid())
           return StmtError();
-        RetValExp = ER.take();
+        RetValExp = ER.get();
       }
     }
 
@@ -2999,7 +2992,7 @@
         // FIXME: Clean up temporaries here anyway?
         return StmtError();
       }
-      RetValExp = Res.takeAs<Expr>();
+      RetValExp = Res.getAs<Expr>();
 
       // If we have a related result type, we need to implicitly
       // convert back to the formal result type.  We can't pretend to
@@ -3013,7 +3006,7 @@
           // FIXME: Clean up temporaries here anyway?
           return StmtError();
         }
-        RetValExp = Res.takeAs<Expr>();
+        RetValExp = Res.getAs<Expr>();
       }
 
       CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
@@ -3024,7 +3017,7 @@
       ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
       if (ER.isInvalid())
         return StmtError();
-      RetValExp = ER.take();
+      RetValExp = ER.get();
     }
     Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
   }
@@ -3034,7 +3027,7 @@
   if (Result->getNRVOCandidate())
     FunctionScopes.back()->Returns.push_back(Result);
 
-  return Owned(Result);
+  return Result;
 }
 
 StmtResult
@@ -3045,12 +3038,12 @@
   if (Var && Var->isInvalidDecl())
     return StmtError();
 
-  return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body));
+  return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body);
 }
 
 StmtResult
 Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
-  return Owned(new (Context) ObjCAtFinallyStmt(AtLoc, Body));
+  return new (Context) ObjCAtFinallyStmt(AtLoc, Body);
 }
 
 StmtResult
@@ -3061,10 +3054,8 @@
 
   getCurFunction()->setHasBranchProtectedScope();
   unsigned NumCatchStmts = CatchStmts.size();
-  return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try,
-                                     CatchStmts.data(),
-                                     NumCatchStmts,
-                                     Finally));
+  return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(),
+                               NumCatchStmts, Finally);
 }
 
 StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
@@ -3073,10 +3064,10 @@
     if (Result.isInvalid())
       return StmtError();
 
-    Result = ActOnFinishFullExpr(Result.take());
+    Result = ActOnFinishFullExpr(Result.get());
     if (Result.isInvalid())
       return StmtError();
-    Throw = Result.take();
+    Throw = Result.get();
 
     QualType ThrowType = Throw->getType();
     // Make sure the expression type is an ObjC pointer or "void *".
@@ -3089,7 +3080,7 @@
     }
   }
 
-  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, Throw));
+  return new (Context) ObjCAtThrowStmt(AtLoc, Throw);
 }
 
 StmtResult
@@ -3115,7 +3106,7 @@
   ExprResult result = DefaultLvalueConversion(operand);
   if (result.isInvalid())
     return ExprError();
-  operand = result.take();
+  operand = result.get();
 
   // Make sure the expression type is an ObjC pointer or "void *".
   QualType type = operand->getType();
@@ -3136,7 +3127,7 @@
                                   Stmt *SyncBody) {
   // We can't jump into or indirect-jump out of a @synchronized block.
   getCurFunction()->setHasBranchProtectedScope();
-  return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody));
+  return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody);
 }
 
 /// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
@@ -3145,15 +3136,14 @@
 Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
                          Stmt *HandlerBlock) {
   // There's nothing to test that ActOnExceptionDecl didn't already test.
-  return Owned(new (Context) CXXCatchStmt(CatchLoc,
-                                          cast_or_null<VarDecl>(ExDecl),
-                                          HandlerBlock));
+  return new (Context)
+      CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);
 }
 
 StmtResult
 Sema::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) {
   getCurFunction()->setHasBranchProtectedScope();
-  return Owned(new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body));
+  return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body);
 }
 
 namespace {
@@ -3197,6 +3187,9 @@
       !getSourceManager().isInSystemHeader(TryLoc))
       Diag(TryLoc, diag::err_exceptions_disabled) << "try";
 
+  if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
+    Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";
+
   const unsigned NumHandlers = Handlers.size();
   assert(NumHandlers > 0 &&
          "The parser shouldn't call this if there are no handlers.");
@@ -3247,7 +3240,7 @@
   // Neither of these are explicitly forbidden, but every compiler detects them
   // and warns.
 
-  return Owned(CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers));
+  return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers);
 }
 
 StmtResult
@@ -3259,7 +3252,7 @@
 
   getCurFunction()->setHasBranchProtectedScope();
 
-  return Owned(SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler));
+  return SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler);
 }
 
 StmtResult
@@ -3274,14 +3267,25 @@
                      << FilterExpr->getType());
   }
 
-  return Owned(SEHExceptStmt::Create(Context,Loc,FilterExpr,Block));
+  return SEHExceptStmt::Create(Context,Loc,FilterExpr,Block);
 }
 
 StmtResult
 Sema::ActOnSEHFinallyBlock(SourceLocation Loc,
                            Stmt *Block) {
   assert(Block);
-  return Owned(SEHFinallyStmt::Create(Context,Loc,Block));
+  return SEHFinallyStmt::Create(Context,Loc,Block);
+}
+
+StmtResult
+Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) {
+  Scope *SEHTryParent = CurScope;
+  while (SEHTryParent && !SEHTryParent->isSEHTryScope())
+    SEHTryParent = SEHTryParent->getParent();
+  if (!SEHTryParent)
+    return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));
+
+  return new (Context) SEHLeaveStmt(Loc);
 }
 
 StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc,
@@ -3474,5 +3478,5 @@
   PopDeclContext();
   PopFunctionScopeInfo();
 
-  return Owned(Res);
+  return Res;
 }
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 6502548..fdab947 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -21,6 +21,7 @@
 #include "clang/Sema/ScopeInfo.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitVector.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
 using namespace clang;
 using namespace sema;
 
@@ -166,7 +167,7 @@
     if (Result.isInvalid())
       return StmtError();
 
-    Exprs[i] = Result.take();
+    Exprs[i] = Result.get();
     InputConstraintInfos.push_back(Info);
 
     const Type *Ty = Exprs[i]->getType().getTypePtr();
@@ -351,7 +352,7 @@
         InputExpr->isEvaluatable(Context)) {
       CastKind castKind =
         (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast);
-      InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).take();
+      InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).get();
       Exprs[InputOpNo] = InputExpr;
       NS->setInputExpr(i, InputExpr);
       continue;
@@ -364,13 +365,13 @@
     return StmtError();
   }
 
-  return Owned(NS);
+  return NS;
 }
 
 ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
                                            SourceLocation TemplateKWLoc,
                                            UnqualifiedId &Id,
-                                           InlineAsmIdentifierInfo &Info,
+                                           llvm::InlineAsmIdentifierInfo &Info,
                                            bool IsUnevaluatedContext) {
   Info.clear();
 
@@ -389,7 +390,7 @@
 
   if (!Result.isUsable()) return Result;
 
-  Result = CheckPlaceholderExpr(Result.take());
+  Result = CheckPlaceholderExpr(Result.get());
   if (!Result.isUsable()) return Result;
 
   QualType T = Result.get()->getType();
@@ -484,5 +485,5 @@
                             /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
                             Constraints, Exprs, AsmString,
                             Clobbers, EndLoc);
-  return Owned(NS);
+  return NS;
 }
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index 3bc620b..44169c2 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -16,6 +16,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Sema/DelayedDiagnostic.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "llvm/ADT/StringExtras.h"
 
@@ -42,6 +43,156 @@
                                            A.getAttributeSpellingListIndex());
 }
 
+static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
+                                SourceRange) {
+  if (St->getStmtClass() != Stmt::DoStmtClass &&
+      St->getStmtClass() != Stmt::ForStmtClass &&
+      St->getStmtClass() != Stmt::CXXForRangeStmtClass &&
+      St->getStmtClass() != Stmt::WhileStmtClass) {
+    S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop);
+    return nullptr;
+  }
+
+  IdentifierLoc *OptionLoc = A.getArgAsIdent(0);
+  IdentifierInfo *OptionInfo = OptionLoc->Ident;
+  IdentifierLoc *ValueLoc = A.getArgAsIdent(1);
+  IdentifierInfo *ValueInfo = ValueLoc->Ident;
+  Expr *ValueExpr = A.getArgAsExpr(2);
+
+  assert(OptionInfo && "Attribute must have valid option info.");
+
+  LoopHintAttr::OptionType Option =
+      llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getName())
+          .Case("vectorize", LoopHintAttr::Vectorize)
+          .Case("vectorize_width", LoopHintAttr::VectorizeWidth)
+          .Case("interleave", LoopHintAttr::Interleave)
+          .Case("interleave_count", LoopHintAttr::InterleaveCount)
+          .Case("unroll", LoopHintAttr::Unroll)
+          .Case("unroll_count", LoopHintAttr::UnrollCount)
+          .Default(LoopHintAttr::Vectorize);
+
+  int ValueInt;
+  if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave ||
+      Option == LoopHintAttr::Unroll) {
+    if (!ValueInfo) {
+      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
+      return nullptr;
+    }
+    if (ValueInfo->isStr("disable"))
+      ValueInt = 0;
+    else if (ValueInfo->isStr("enable"))
+      ValueInt = 1;
+    else {
+      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
+      return nullptr;
+    }
+  } else if (Option == LoopHintAttr::VectorizeWidth ||
+             Option == LoopHintAttr::InterleaveCount ||
+             Option == LoopHintAttr::UnrollCount) {
+    // FIXME: We should support template parameters for the loop hint value.
+    // See bug report #19610.
+    llvm::APSInt ValueAPS;
+    if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context) ||
+        (ValueInt = ValueAPS.getSExtValue()) < 1) {
+      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value);
+      return nullptr;
+    }
+  } else
+    llvm_unreachable("Unknown loop hint option");
+
+  return LoopHintAttr::CreateImplicit(S.Context, Option, ValueInt,
+                                      A.getRange());
+}
+
+static void
+CheckForIncompatibleAttributes(Sema &S, SmallVectorImpl<const Attr *> &Attrs) {
+  // There are 3 categories of loop hints: vectorize, interleave, and
+  // unroll. Each comes in two variants: an enable/disable form and a
+  // form which takes a numeric argument. For example:
+  // unroll(enable|disable) and unroll_count(N). The following array
+  // accumulate the hints encountered while iterating through the
+  // attributes to check for compatibility.
+  struct {
+    int EnableOptionId;
+    int NumericOptionId;
+    bool EnabledIsSet;
+    bool ValueIsSet;
+    bool Enabled;
+    int Value;
+  } Options[] = {{LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth, false,
+                  false, false, 0},
+                 {LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount,
+                  false, false, false, 0},
+                 {LoopHintAttr::Unroll, LoopHintAttr::UnrollCount, false, false,
+                  false, 0}};
+
+  for (const auto *I : Attrs) {
+    const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
+
+    // Skip non loop hint attributes
+    if (!LH)
+      continue;
+
+    int Option = LH->getOption();
+    int ValueInt = LH->getValue();
+
+    int Category;
+    switch (Option) {
+    case LoopHintAttr::Vectorize:
+    case LoopHintAttr::VectorizeWidth:
+      Category = 0;
+      break;
+    case LoopHintAttr::Interleave:
+    case LoopHintAttr::InterleaveCount:
+      Category = 1;
+      break;
+    case LoopHintAttr::Unroll:
+    case LoopHintAttr::UnrollCount:
+      Category = 2;
+      break;
+    };
+
+    auto &CategoryState = Options[Category];
+    SourceLocation ValueLoc = LH->getRange().getEnd();
+    if (Option == LoopHintAttr::Vectorize ||
+        Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {
+      // Enable|disable hint.  For example, vectorize(enable).
+      if (CategoryState.EnabledIsSet) {
+        // Cannot specify enable/disable state twice.
+        S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+            << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)
+            << LoopHintAttr::getValueName(CategoryState.Enabled)
+            << LoopHintAttr::getOptionName(Option)
+            << LoopHintAttr::getValueName(ValueInt);
+      }
+      CategoryState.EnabledIsSet = true;
+      CategoryState.Enabled = ValueInt;
+    } else {
+      // Numeric hint.  For example, unroll_count(8).
+      if (CategoryState.ValueIsSet) {
+        // Cannot specify numeric hint twice.
+        S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+            << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)
+            << CategoryState.Value << LoopHintAttr::getOptionName(Option)
+            << ValueInt;
+      }
+      CategoryState.ValueIsSet = true;
+      CategoryState.Value = ValueInt;
+    }
+
+    if (CategoryState.EnabledIsSet && !CategoryState.Enabled &&
+        CategoryState.ValueIsSet) {
+      // Disable hints are not compatible with numeric hints of the
+      // same category.
+      S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+          << /*Duplicate=*/false
+          << LoopHintAttr::getOptionName(CategoryState.EnableOptionId)
+          << LoopHintAttr::getValueName(CategoryState.Enabled)
+          << LoopHintAttr::getOptionName(CategoryState.NumericOptionId)
+          << CategoryState.Value;
+    }
+  }
+}
 
 static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
                                   SourceRange Range) {
@@ -53,6 +204,8 @@
     return nullptr;
   case AttributeList::AT_FallThrough:
     return handleFallThroughAttr(S, St, A, Range);
+  case AttributeList::AT_LoopHint:
+    return handleLoopHintAttr(S, St, A, Range);
   default:
     // if we're here, then we parsed a known attribute, but didn't recognize
     // it as a statement attribute => it is declaration attribute
@@ -70,6 +223,8 @@
       Attrs.push_back(a);
   }
 
+  CheckForIncompatibleAttributes(*this, Attrs);
+
   if (Attrs.empty())
     return S;
 
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 272c811..5a18845 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -421,15 +421,10 @@
     // perform the double-lookup check.
     NamedDecl *FirstQualifierInScope = nullptr;
 
-    return Owned(CXXDependentScopeMemberExpr::Create(Context,
-                                                     /*This*/ nullptr, ThisType,
-                                                     /*IsArrow*/ true,
-                                                     /*Op*/ SourceLocation(),
-                                               SS.getWithLocInContext(Context),
-                                                     TemplateKWLoc,
-                                                     FirstQualifierInScope,
-                                                     NameInfo,
-                                                     TemplateArgs));
+    return CXXDependentScopeMemberExpr::Create(
+        Context, /*This*/ nullptr, ThisType, /*IsArrow*/ true,
+        /*Op*/ SourceLocation(), SS.getWithLocInContext(Context), TemplateKWLoc,
+        FirstQualifierInScope, NameInfo, TemplateArgs);
   }
 
   return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs);
@@ -440,11 +435,9 @@
                                 SourceLocation TemplateKWLoc,
                                 const DeclarationNameInfo &NameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs) {
-  return Owned(DependentScopeDeclRefExpr::Create(Context,
-                                               SS.getWithLocInContext(Context),
-                                                 TemplateKWLoc,
-                                                 NameInfo,
-                                                 TemplateArgs));
+  return DependentScopeDeclRefExpr::Create(
+      Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+      TemplateArgs);
 }
 
 /// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
@@ -551,7 +544,7 @@
 /// ParamNameLoc is the location of the parameter name (if any).
 /// If the type parameter has a default argument, it will be added
 /// later via ActOnTypeParameterDefault.
-Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename,
                                SourceLocation EllipsisLoc,
                                SourceLocation KeyLoc,
                                IdentifierInfo *ParamName,
@@ -567,10 +560,11 @@
   if (!ParamName)
     Loc = KeyLoc;
 
+  bool IsParameterPack = EllipsisLoc.isValid();
   TemplateTypeParmDecl *Param
     = TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
                                    KeyLoc, Loc, Depth, Position, ParamName,
-                                   Typename, Ellipsis);
+                                   Typename, IsParameterPack);
   Param->setAccess(AS_public);
   if (Invalid)
     Param->setInvalidDecl();
@@ -586,7 +580,7 @@
   // C++0x [temp.param]p9:
   //   A default template-argument may be specified for any kind of
   //   template-parameter that is not a template parameter pack.
-  if (DefaultArg && Ellipsis) {
+  if (DefaultArg && IsParameterPack) {
     Diag(EqualLoc, diag::err_template_param_pack_default_arg);
     DefaultArg = ParsedType();
   }
@@ -731,7 +725,7 @@
       Param->setInvalidDecl();
       return Param;
     }
-    Default = DefaultRes.take();
+    Default = DefaultRes.get();
 
     Param->setDefaultArgument(Default, false);
   }
@@ -2125,8 +2119,7 @@
     // corresponds to these arguments.
     void *InsertPos = nullptr;
     ClassTemplateSpecializationDecl *Decl
-      = ClassTemplate->findSpecialization(Converted.data(), Converted.size(),
-                                          InsertPos);
+      = ClassTemplate->findSpecialization(Converted, InsertPos);
     if (!Decl) {
       // This is the first time we have referenced this class template
       // specialization. Create the canonical declaration and add it to
@@ -2506,11 +2499,9 @@
 
   if (IsPartialSpecialization)
     // FIXME: Template parameter list matters too
-    PrevDecl = VarTemplate->findPartialSpecialization(
-        Converted.data(), Converted.size(), InsertPos);
+    PrevDecl = VarTemplate->findPartialSpecialization(Converted, InsertPos);
   else
-    PrevDecl = VarTemplate->findSpecialization(Converted.data(),
-                                               Converted.size(), InsertPos);
+    PrevDecl = VarTemplate->findSpecialization(Converted, InsertPos);
 
   VarTemplateSpecializationDecl *Specialization = nullptr;
 
@@ -2675,7 +2666,7 @@
   // corresponds to these arguments.
   void *InsertPos = nullptr;
   if (VarTemplateSpecializationDecl *Spec = Template->findSpecialization(
-          Converted.data(), Converted.size(), InsertPos))
+          Converted, InsertPos))
     // If we already have a variable template specialization, return it.
     return Spec;
 
@@ -2869,7 +2860,7 @@
                                    RequiresADL, TemplateArgs,
                                    R.begin(), R.end());
 
-  return Owned(ULE);
+  return ULE;
 }
 
 // We actually only call this from template instantiation.
@@ -2903,7 +2894,7 @@
   if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
     Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
       << SS.getScopeRep()
-      << NameInfo.getName() << SS.getRange();
+      << NameInfo.getName().getAsString() << SS.getRange();
     Diag(Temp->getLocation(), diag::note_referenced_class_template);
     return ExprError();
   }
@@ -3005,9 +2996,11 @@
 }
 
 bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
-                                     const TemplateArgumentLoc &AL,
+                                     TemplateArgumentLoc &AL,
                           SmallVectorImpl<TemplateArgument> &Converted) {
   const TemplateArgument &Arg = AL.getArgument();
+  QualType ArgType;
+  TypeSourceInfo *TSI = nullptr;
 
   // Check template type parameter.
   switch(Arg.getKind()) {
@@ -3015,6 +3008,8 @@
     // C++ [temp.arg.type]p1:
     //   A template-argument for a template-parameter which is a
     //   type shall be a type-id.
+    ArgType = Arg.getAsType();
+    TSI = AL.getTypeSourceInfo();
     break;
   case TemplateArgument::Template: {
     // We have a template type parameter but the template argument
@@ -3049,18 +3044,38 @@
       }
     }
 
-    if (NameInfo.getName().isIdentifier()) {
+    if (auto *II = NameInfo.getName().getAsIdentifierInfo()) {
       LookupResult Result(*this, NameInfo, LookupOrdinaryName);
       LookupParsedName(Result, CurScope, &SS);
 
       if (Result.getAsSingle<TypeDecl>() ||
           Result.getResultKind() ==
-            LookupResult::NotFoundInCurrentInstantiation) {
-        // FIXME: Add a FixIt and fix up the template argument for recovery.
+              LookupResult::NotFoundInCurrentInstantiation) {
+        // Suggest that the user add 'typename' before the NNS.
         SourceLocation Loc = AL.getSourceRange().getBegin();
-        Diag(Loc, diag::err_template_arg_must_be_type_suggest);
+        Diag(Loc, getLangOpts().MSVCCompat
+                      ? diag::ext_ms_template_type_arg_missing_typename
+                      : diag::err_template_arg_must_be_type_suggest)
+            << FixItHint::CreateInsertion(Loc, "typename ");
         Diag(Param->getLocation(), diag::note_template_param_here);
-        return true;
+
+        // Recover by synthesizing a type using the location information that we
+        // already have.
+        ArgType =
+            Context.getDependentNameType(ETK_Typename, SS.getScopeRep(), II);
+        TypeLocBuilder TLB;
+        DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(ArgType);
+        TL.setElaboratedKeywordLoc(SourceLocation(/*synthesized*/));
+        TL.setQualifierLoc(SS.getWithLocInContext(Context));
+        TL.setNameLoc(NameInfo.getLoc());
+        TSI = TLB.getTypeSourceInfo(Context, ArgType);
+
+        // Overwrite our input TemplateArgumentLoc so that we can recover
+        // properly.
+        AL = TemplateArgumentLoc(TemplateArgument(ArgType),
+                                 TemplateArgumentLocInfo(TSI));
+
+        break;
       }
     }
     // fallthrough
@@ -3076,11 +3091,11 @@
   }
   }
 
-  if (CheckTemplateArgument(Param, AL.getTypeSourceInfo()))
+  if (CheckTemplateArgument(Param, TSI))
     return true;
 
   // Add the converted template type argument.
-  QualType ArgType = Context.getCanonicalType(Arg.getAsType());
+  ArgType = Context.getCanonicalType(ArgType);
   
   // Objective-C ARC:
   //   If an explicitly-specified template argument type is a lifetime type
@@ -3310,7 +3325,7 @@
     if (Arg.isInvalid())
       return TemplateArgumentLoc();
 
-    Expr *ArgE = Arg.takeAs<Expr>();
+    Expr *ArgE = Arg.getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(ArgE), ArgE);
   }
 
@@ -3362,7 +3377,7 @@
 ///
 /// \returns true on error, false otherwise.
 bool Sema::CheckTemplateArgument(NamedDecl *Param,
-                                 const TemplateArgumentLoc &Arg,
+                                 TemplateArgumentLoc &Arg,
                                  NamedDecl *Template,
                                  SourceLocation TemplateLoc,
                                  SourceLocation RAngleLoc,
@@ -3452,22 +3467,20 @@
         // so it was provided with a template keyword. However, its source
         // location is not stored in the template argument structure.
         SourceLocation TemplateKWLoc;
-        ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context,
-                                                SS.getWithLocInContext(Context),
-                                                               TemplateKWLoc,
-                                                               NameInfo,
-                                                               nullptr));
+        ExprResult E = DependentScopeDeclRefExpr::Create(
+            Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+            nullptr);
 
         // If we parsed the template argument as a pack expansion, create a
         // pack expansion expression.
         if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){
-          E = ActOnPackExpansion(E.take(), Arg.getTemplateEllipsisLoc());
+          E = ActOnPackExpansion(E.get(), Arg.getTemplateEllipsisLoc());
           if (E.isInvalid())
             return true;
         }
 
         TemplateArgument Result;
-        E = CheckTemplateArgument(NTTP, NTTPType, E.take(), Result);
+        E = CheckTemplateArgument(NTTP, NTTPType, E.get(), Result);
         if (E.isInvalid())
           return true;
 
@@ -3817,7 +3830,7 @@
       if (E.isInvalid())
         return true;
 
-      Expr *Ex = E.takeAs<Expr>();
+      Expr *Ex = E.getAs<Expr>();
       Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex);
     } else {
       TemplateTemplateParmDecl *TempParm
@@ -3864,6 +3877,17 @@
     ++ArgIdx;
   }
 
+  // If we're performing a partial argument substitution, allow any trailing
+  // pack expansions; they might be empty. This can happen even if
+  // PartialTemplateArgs is false (the list of arguments is complete but
+  // still dependent).
+  if (ArgIdx < NumArgs && CurrentInstantiationScope &&
+      CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+    while (ArgIdx < NumArgs &&
+           TemplateArgs[ArgIdx].getArgument().isPackExpansion())
+      Converted.push_back(TemplateArgs[ArgIdx++].getArgument());
+  }
+
   // If we have any leftover arguments, then there were too many arguments.
   // Complain and fail.
   if (ArgIdx < NumArgs)
@@ -4134,12 +4158,17 @@
   //
   // C++11 allows these, and even in C++03 we allow them as an extension with
   // a warning.
-  if (LangOpts.CPlusPlus11 ?
-     Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_unnamed_type,
-                              SR.getBegin()) != DiagnosticsEngine::Ignored ||
-      Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_local_type,
-                               SR.getBegin()) != DiagnosticsEngine::Ignored :
-      Arg->hasUnnamedOrLocalType()) {
+  bool NeedsCheck;
+  if (LangOpts.CPlusPlus11)
+    NeedsCheck =
+        !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_unnamed_type,
+                         SR.getBegin()) ||
+        !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_local_type,
+                         SR.getBegin());
+  else
+    NeedsCheck = Arg->hasUnnamedOrLocalType();
+
+  if (NeedsCheck) {
     UnnamedLocalNoLinkageFinder Finder(*this, SR);
     (void)Finder.Visit(Context.getCanonicalType(Arg));
   }
@@ -4161,14 +4190,14 @@
   if (Arg->isValueDependent() || Arg->isTypeDependent())
     return NPV_NotNullPointer;
   
-  if (!S.getLangOpts().CPlusPlus11)
+  if (!S.getLangOpts().CPlusPlus11 || S.getLangOpts().MSVCCompat)
     return NPV_NotNullPointer;
   
   // Determine whether we have a constant expression.
   ExprResult ArgRV = S.DefaultFunctionArrayConversion(Arg);
   if (ArgRV.isInvalid())
     return NPV_Error;
-  Arg = ArgRV.take();
+  Arg = ArgRV.get();
   
   Expr::EvalResult EvalResult;
   SmallVector<PartialDiagnosticAt, 8> Notes;
@@ -4308,22 +4337,6 @@
   Expr *Arg = ArgIn;
   QualType ArgType = Arg->getType();
 
-  // If our parameter has pointer type, check for a null template value.
-  if (ParamType->isPointerType() || ParamType->isNullPtrType()) {
-    switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) {
-    case NPV_NullPointer:
-      S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
-      Converted = TemplateArgument(ParamType, /*isNullPtr*/true);
-      return false;
-
-    case NPV_Error:
-      return true;
-        
-    case NPV_NotNullPointer:
-      break;
-    }
-  }
-
   bool AddressTaken = false;
   SourceLocation AddrOpLoc;
   if (S.getLangOpts().MicrosoftExt) {
@@ -4411,6 +4424,32 @@
       Arg = subst->getReplacement()->IgnoreImpCasts();
   }
 
+  DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg);
+  ValueDecl *Entity = DRE ? DRE->getDecl() : nullptr;
+
+  // If our parameter has pointer type, check for a null template value.
+  if (ParamType->isPointerType() || ParamType->isNullPtrType()) {
+    NullPointerValueKind NPV;
+    // dllimport'd entities aren't constant but are available inside of template
+    // arguments.
+    if (Entity && Entity->hasAttr<DLLImportAttr>())
+      NPV = NPV_NotNullPointer;
+    else
+      NPV = isNullPointerValueTemplateArgument(S, Param, ParamType, ArgIn);
+    switch (NPV) {
+    case NPV_NullPointer:
+      S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
+      Converted = TemplateArgument(ParamType, /*isNullPtr=*/true);
+      return false;
+
+    case NPV_Error:
+      return true;
+
+    case NPV_NotNullPointer:
+      break;
+    }
+  }
+
   // Stop checking the precise nature of the argument if it is value dependent,
   // it should be checked when instantiated.
   if (Arg->isValueDependent()) {
@@ -4427,7 +4466,6 @@
     return false;
   }
 
-  DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg);
   if (!DRE) {
     S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref)
     << Arg->getSourceRange();
@@ -4435,8 +4473,6 @@
     return true;
   }
 
-  ValueDecl *Entity = DRE->getDecl();
-
   // Cannot refer to non-static data members
   if (isa<FieldDecl>(Entity) || isa<IndirectFieldDecl>(Entity)) {
     S.Diag(Arg->getLocStart(), diag::err_template_arg_field)
@@ -4611,7 +4647,7 @@
                                   ParamType.getNonReferenceType(),
                                   false, ObjCLifetimeConversion)) {
     Arg = S.ImpCastExprToType(Arg, ParamType, CK_NoOp,
-                              Arg->getValueKind()).take();
+                              Arg->getValueKind()).get();
     ResultArg = Arg;
   } else if (!S.Context.hasSameUnqualifiedType(Arg->getType(),
                 ParamType.getNonReferenceType())) {
@@ -4732,7 +4768,7 @@
   if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) {
     // FIXME: Produce a cloned, canonical expression?
     Converted = TemplateArgument(Arg);
-    return Owned(Arg);
+    return Arg;
   }
 
   // C++ [temp.arg.nontype]p5:
@@ -4776,7 +4812,7 @@
       // we should be able to diagnose that prior to instantiation.
       if (Arg->isValueDependent()) {
         Converted = TemplateArgument(Arg);
-        return Owned(Arg);
+        return Arg;
       }
 
       // C++ [temp.arg.nontype]p1:
@@ -4809,7 +4845,7 @@
     ExprResult ArgResult = DefaultLvalueConversion(Arg);
     if (ArgResult.isInvalid())
       return ExprError();
-    Arg = ArgResult.take();
+    Arg = ArgResult.get();
 
     QualType ArgType = Arg->getType();
 
@@ -4842,7 +4878,7 @@
       } Diagnoser(ArgType);
 
       Arg = VerifyIntegerConstantExpression(Arg, &Value, Diagnoser,
-                                            false).take();
+                                            false).get();
       if (!Arg)
         return ExprError();
     }
@@ -4857,11 +4893,11 @@
       // Okay: no conversion necessary
     } else if (ParamType->isBooleanType()) {
       // This is an integral-to-boolean conversion.
-      Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take();
+      Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).get();
     } else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
                !ParamType->isEnumeralType()) {
       // This is an integral promotion or conversion.
-      Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take();
+      Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).get();
     } else {
       // We can't perform this conversion.
       Diag(Arg->getLocStart(),
@@ -4878,7 +4914,7 @@
       // The argument is value-dependent. Create a new
       // TemplateArgument with the converted expression.
       Converted = TemplateArgument(Arg);
-      return Owned(Arg);
+      return Arg;
     }
 
     QualType IntegerType = Context.getCanonicalType(ParamType);
@@ -4932,7 +4968,7 @@
                                  ParamType->isEnumeralType() 
                                    ? Context.getCanonicalType(ParamType)
                                    : IntegerType);
-    return Owned(Arg);
+    return Arg;
   }
 
   QualType ArgType = Arg->getType();
@@ -4980,13 +5016,13 @@
                                                          ParamType,
                                                          Arg, Converted))
         return ExprError();
-      return Owned(Arg);
+      return Arg;
     }
 
     if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg,
                                              Converted))
       return ExprError();
-    return Owned(Arg);
+    return Arg;
   }
 
   if (ParamType->isPointerType()) {
@@ -5001,7 +5037,7 @@
                                                        ParamType,
                                                        Arg, Converted))
       return ExprError();
-    return Owned(Arg);
+    return Arg;
   }
 
   if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
@@ -5032,14 +5068,14 @@
                                                        ParamType,
                                                        Arg, Converted))
       return ExprError();
-    return Owned(Arg);
+    return Arg;
   }
 
   // Deal with parameters of type std::nullptr_t.
   if (ParamType->isNullPtrType()) {
     if (Arg->isTypeDependent() || Arg->isValueDependent()) {
       Converted = TemplateArgument(Arg);
-      return Owned(Arg);
+      return Arg;
     }
     
     switch (isNullPointerValueTemplateArgument(*this, Param, ParamType, Arg)) {
@@ -5055,7 +5091,7 @@
     case NPV_NullPointer:
       Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
       Converted = TemplateArgument(ParamType, /*isNullPtr*/true);
-      return Owned(Arg);
+      return Arg;
     }
   }
 
@@ -5066,7 +5102,7 @@
   if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg,
                                            Converted))
     return ExprError();
-  return Owned(Arg);
+  return Arg;
 }
 
 /// \brief Check a template argument against its corresponding
@@ -5075,7 +5111,7 @@
 /// This routine implements the semantics of C++ [temp.arg.template].
 /// It returns true if an error occurred, and false otherwise.
 bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
-                                 const TemplateArgumentLoc &Arg,
+                                 TemplateArgumentLoc &Arg,
                                  unsigned ArgumentPackIndex) {
   TemplateName Name = Arg.getArgument().getAsTemplateOrTemplatePattern();
   TemplateDecl *Template = Name.getAsTemplateDecl();
@@ -5192,7 +5228,7 @@
       if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
                                     ParamType.getUnqualifiedType(), false,
                                     ObjCLifetimeConversion))
-        RefExpr = ImpCastExprToType(RefExpr.take(), ParamType.getUnqualifiedType(), CK_NoOp);
+        RefExpr = ImpCastExprToType(RefExpr.get(), ParamType.getUnqualifiedType(), CK_NoOp);
 
       assert(!RefExpr.isInvalid() &&
              Context.hasSameType(((Expr*) RefExpr.get())->getType(),
@@ -5212,7 +5248,7 @@
 
     if (T->isFunctionType() || T->isArrayType()) {
       // Decay functions and arrays.
-      RefExpr = DefaultFunctionArrayConversion(RefExpr.take());
+      RefExpr = DefaultFunctionArrayConversion(RefExpr.get());
       if (RefExpr.isInvalid())
         return ExprError();
 
@@ -5295,7 +5331,7 @@
                                Loc, Loc);
   }
   
-  return Owned(E);
+  return E;
 }
 
 /// \brief Match two template parameters within template parameter lists.
@@ -6048,14 +6084,9 @@
 
   if (isPartialSpecialization)
     // FIXME: Template parameter list matters, too
-    PrevDecl
-      = ClassTemplate->findPartialSpecialization(Converted.data(),
-                                                 Converted.size(),
-                                                 InsertPos);
+    PrevDecl = ClassTemplate->findPartialSpecialization(Converted, InsertPos);
   else
-    PrevDecl
-      = ClassTemplate->findSpecialization(Converted.data(),
-                                          Converted.size(), InsertPos);
+    PrevDecl = ClassTemplate->findSpecialization(Converted, InsertPos);
 
   ClassTemplateSpecializationDecl *Specialization = nullptr;
 
@@ -7065,8 +7096,7 @@
   // corresponds to these arguments.
   void *InsertPos = nullptr;
   ClassTemplateSpecializationDecl *PrevDecl
-    = ClassTemplate->findSpecialization(Converted.data(),
-                                        Converted.size(), InsertPos);
+    = ClassTemplate->findSpecialization(Converted, InsertPos);
 
   TemplateSpecializationKind PrevDecl_TSK
     = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 246107e..f941a09 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -297,6 +297,7 @@
                                       XAEnd = X.pack_end(),
                                          YA = Y.pack_begin();
          XA != XAEnd; ++XA, ++YA) {
+      // FIXME: Do we need to merge the results together here?
       if (checkDeducedTemplateArguments(Context,
                     DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
                     DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()))
@@ -581,96 +582,181 @@
   return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
 }
 
-typedef SmallVector<SmallVector<DeducedTemplateArgument, 4>, 2>
-  NewlyDeducedPacksType;
+/// A pack that we're currently deducing.
+struct clang::DeducedPack {
+  DeducedPack(unsigned Index) : Index(Index), Outer(nullptr) {}
 
-/// \brief Prepare to perform template argument deduction for all of the
-/// arguments in a set of argument packs.
-static void
-PrepareArgumentPackDeduction(Sema &S,
-                           SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                           ArrayRef<unsigned> PackIndices,
-                           SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
-                           NewlyDeducedPacksType &NewlyDeducedPacks) {
-  // Save the deduced template arguments for each parameter pack expanded
-  // by this pack expansion, then clear out the deduction.
-  for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-    // Save the previously-deduced argument pack, then clear it out so that we
-    // can deduce a new argument pack.
-    SavedPacks[I] = Deduced[PackIndices[I]];
-    Deduced[PackIndices[I]] = TemplateArgument();
+  // The index of the pack.
+  unsigned Index;
 
-    if (!S.CurrentInstantiationScope)
-      continue;
+  // The old value of the pack before we started deducing it.
+  DeducedTemplateArgument Saved;
 
-    // If the template argument pack was explicitly specified, add that to
-    // the set of deduced arguments.
-    const TemplateArgument *ExplicitArgs;
-    unsigned NumExplicitArgs;
-    if (NamedDecl *PartiallySubstitutedPack
-        = S.CurrentInstantiationScope->getPartiallySubstitutedPack(
-                                                           &ExplicitArgs,
-                                                           &NumExplicitArgs)) {
-      if (getDepthAndIndex(PartiallySubstitutedPack).second == PackIndices[I])
-        NewlyDeducedPacks[I].append(ExplicitArgs,
-                                    ExplicitArgs + NumExplicitArgs);
+  // A deferred value of this pack from an inner deduction, that couldn't be
+  // deduced because this deduction hadn't happened yet.
+  DeducedTemplateArgument DeferredDeduction;
+
+  // The new value of the pack.
+  SmallVector<DeducedTemplateArgument, 4> New;
+
+  // The outer deduction for this pack, if any.
+  DeducedPack *Outer;
+};
+
+/// A scope in which we're performing pack deduction.
+class PackDeductionScope {
+public:
+  PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
+                     SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                     TemplateDeductionInfo &Info, TemplateArgument Pattern)
+      : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
+    // Compute the set of template parameter indices that correspond to
+    // parameter packs expanded by the pack expansion.
+    {
+      llvm::SmallBitVector SawIndices(TemplateParams->size());
+      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+      S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
+      for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
+        unsigned Depth, Index;
+        std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
+        if (Depth == 0 && !SawIndices[Index]) {
+          SawIndices[Index] = true;
+
+          // Save the deduced template argument for the parameter pack expanded
+          // by this pack expansion, then clear out the deduction.
+          DeducedPack Pack(Index);
+          Pack.Saved = Deduced[Index];
+          Deduced[Index] = TemplateArgument();
+
+          Packs.push_back(Pack);
+        }
+      }
+    }
+    assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
+
+    for (auto &Pack : Packs) {
+      if (Info.PendingDeducedPacks.size() > Pack.Index)
+        Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
+      else
+        Info.PendingDeducedPacks.resize(Pack.Index + 1);
+      Info.PendingDeducedPacks[Pack.Index] = &Pack;
+
+      if (S.CurrentInstantiationScope) {
+        // If the template argument pack was explicitly specified, add that to
+        // the set of deduced arguments.
+        const TemplateArgument *ExplicitArgs;
+        unsigned NumExplicitArgs;
+        NamedDecl *PartiallySubstitutedPack =
+            S.CurrentInstantiationScope->getPartiallySubstitutedPack(
+                &ExplicitArgs, &NumExplicitArgs);
+        if (PartiallySubstitutedPack &&
+            getDepthAndIndex(PartiallySubstitutedPack).second == Pack.Index)
+          Pack.New.append(ExplicitArgs, ExplicitArgs + NumExplicitArgs);
+      }
     }
   }
-}
 
-/// \brief Finish template argument deduction for a set of argument packs,
-/// producing the argument packs and checking for consistency with prior
-/// deductions.
-static Sema::TemplateDeductionResult
-FinishArgumentPackDeduction(Sema &S,
-                           TemplateParameterList *TemplateParams,
-                           bool HasAnyArguments,
-                           SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                           ArrayRef<unsigned> PackIndices,
-                           SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
-                           NewlyDeducedPacksType &NewlyDeducedPacks,
-                           TemplateDeductionInfo &Info) {
-  // Build argument packs for each of the parameter packs expanded by this
-  // pack expansion.
-  for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-    if (HasAnyArguments && NewlyDeducedPacks[I].empty()) {
-      // We were not able to deduce anything for this parameter pack,
-      // so just restore the saved argument pack.
-      Deduced[PackIndices[I]] = SavedPacks[I];
-      continue;
-    }
-
-    DeducedTemplateArgument NewPack;
-
-    if (NewlyDeducedPacks[I].empty()) {
-      // If we deduced an empty argument pack, create it now.
-      NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack());
-    } else {
-      TemplateArgument *ArgumentPack
-        = new (S.Context) TemplateArgument [NewlyDeducedPacks[I].size()];
-      std::copy(NewlyDeducedPacks[I].begin(), NewlyDeducedPacks[I].end(),
-                ArgumentPack);
-      NewPack
-        = DeducedTemplateArgument(TemplateArgument(ArgumentPack,
-                                                   NewlyDeducedPacks[I].size()),
-                            NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
-    }
-
-    DeducedTemplateArgument Result
-      = checkDeducedTemplateArguments(S.Context, SavedPacks[I], NewPack);
-    if (Result.isNull()) {
-      Info.Param
-        = makeTemplateParameter(TemplateParams->getParam(PackIndices[I]));
-      Info.FirstArg = SavedPacks[I];
-      Info.SecondArg = NewPack;
-      return Sema::TDK_Inconsistent;
-    }
-
-    Deduced[PackIndices[I]] = Result;
+  ~PackDeductionScope() {
+    for (auto &Pack : Packs)
+      Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
   }
 
-  return Sema::TDK_Success;
-}
+  /// Move to deducing the next element in each pack that is being deduced.
+  void nextPackElement() {
+    // Capture the deduced template arguments for each parameter pack expanded
+    // by this pack expansion, add them to the list of arguments we've deduced
+    // for that pack, then clear out the deduced argument.
+    for (auto &Pack : Packs) {
+      DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
+      if (!DeducedArg.isNull()) {
+        Pack.New.push_back(DeducedArg);
+        DeducedArg = DeducedTemplateArgument();
+      }
+    }
+  }
+
+  /// \brief Finish template argument deduction for a set of argument packs,
+  /// producing the argument packs and checking for consistency with prior
+  /// deductions.
+  Sema::TemplateDeductionResult finish(bool HasAnyArguments) {
+    // Build argument packs for each of the parameter packs expanded by this
+    // pack expansion.
+    for (auto &Pack : Packs) {
+      // Put back the old value for this pack.
+      Deduced[Pack.Index] = Pack.Saved;
+
+      // Build or find a new value for this pack.
+      DeducedTemplateArgument NewPack;
+      if (HasAnyArguments && Pack.New.empty()) {
+        if (Pack.DeferredDeduction.isNull()) {
+          // We were not able to deduce anything for this parameter pack
+          // (because it only appeared in non-deduced contexts), so just
+          // restore the saved argument pack.
+          continue;
+        }
+
+        NewPack = Pack.DeferredDeduction;
+        Pack.DeferredDeduction = TemplateArgument();
+      } else if (Pack.New.empty()) {
+        // If we deduced an empty argument pack, create it now.
+        NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack());
+      } else {
+        TemplateArgument *ArgumentPack =
+            new (S.Context) TemplateArgument[Pack.New.size()];
+        std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
+        NewPack = DeducedTemplateArgument(
+            TemplateArgument(ArgumentPack, Pack.New.size()),
+            Pack.New[0].wasDeducedFromArrayBound());
+      }
+
+      // Pick where we're going to put the merged pack.
+      DeducedTemplateArgument *Loc;
+      if (Pack.Outer) {
+        if (Pack.Outer->DeferredDeduction.isNull()) {
+          // Defer checking this pack until we have a complete pack to compare
+          // it against.
+          Pack.Outer->DeferredDeduction = NewPack;
+          continue;
+        }
+        Loc = &Pack.Outer->DeferredDeduction;
+      } else {
+        Loc = &Deduced[Pack.Index];
+      }
+
+      // Check the new pack matches any previous value.
+      DeducedTemplateArgument OldPack = *Loc;
+      DeducedTemplateArgument Result =
+          checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
+
+      // If we deferred a deduction of this pack, check that one now too.
+      if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
+        OldPack = Result;
+        NewPack = Pack.DeferredDeduction;
+        Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
+      }
+
+      if (Result.isNull()) {
+        Info.Param =
+            makeTemplateParameter(TemplateParams->getParam(Pack.Index));
+        Info.FirstArg = OldPack;
+        Info.SecondArg = NewPack;
+        return Sema::TDK_Inconsistent;
+      }
+
+      *Loc = Result;
+    }
+
+    return Sema::TDK_Success;
+  }
+
+private:
+  Sema &S;
+  TemplateParameterList *TemplateParams;
+  SmallVectorImpl<DeducedTemplateArgument> &Deduced;
+  TemplateDeductionInfo &Info;
+
+  SmallVector<DeducedPack, 2> Packs;
+};
 
 /// \brief Deduce the template arguments by comparing the list of parameter
 /// types to the list of argument types, as in the parameter-type-lists of
@@ -773,33 +859,8 @@
     //   comparison deduces template arguments for subsequent positions in the
     //   template parameter packs expanded by the function parameter pack.
 
-    // Compute the set of template parameter indices that correspond to
-    // parameter packs expanded by the pack expansion.
-    SmallVector<unsigned, 2> PackIndices;
     QualType Pattern = Expansion->getPattern();
-    {
-      llvm::SmallBitVector SawIndices(TemplateParams->size());
-      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
-      for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
-        unsigned Depth, Index;
-        std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
-        if (Depth == 0 && !SawIndices[Index]) {
-          SawIndices[Index] = true;
-          PackIndices.push_back(Index);
-        }
-      }
-    }
-    assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
-
-    // Keep track of the deduced template arguments for each parameter pack
-    // expanded by this pack expansion (the outer index) and for each
-    // template argument (the inner SmallVectors).
-    NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
-    SmallVector<DeducedTemplateArgument, 2>
-      SavedPacks(PackIndices.size());
-    PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
-                                 NewlyDeducedPacks);
+    PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
 
     bool HasAnyArguments = false;
     for (; ArgIdx < NumArgs; ++ArgIdx) {
@@ -813,24 +874,12 @@
                                                  RefParamComparisons))
         return Result;
 
-      // Capture the deduced template arguments for each parameter pack expanded
-      // by this pack expansion, add them to the list of arguments we've deduced
-      // for that pack, then clear out the deduced argument.
-      for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-        DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
-        if (!DeducedArg.isNull()) {
-          NewlyDeducedPacks[I].push_back(DeducedArg);
-          DeducedArg = DeducedTemplateArgument();
-        }
-      }
+      PackScope.nextPackElement();
     }
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (Sema::TemplateDeductionResult Result
-          = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
-                                        Deduced, PackIndices, SavedPacks,
-                                        NewlyDeducedPacks, Info))
+    if (auto Result = PackScope.finish(HasAnyArguments))
       return Result;
   }
 
@@ -1852,41 +1901,18 @@
     //   template parameter packs expanded by Pi.
     TemplateArgument Pattern = Params[ParamIdx].getPackExpansionPattern();
 
-    // Compute the set of template parameter indices that correspond to
-    // parameter packs expanded by the pack expansion.
-    SmallVector<unsigned, 2> PackIndices;
-    {
-      llvm::SmallBitVector SawIndices(TemplateParams->size());
-      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
-      for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
-        unsigned Depth, Index;
-        std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
-        if (Depth == 0 && !SawIndices[Index]) {
-          SawIndices[Index] = true;
-          PackIndices.push_back(Index);
-        }
-      }
-    }
-    assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
-
     // FIXME: If there are no remaining arguments, we can bail out early
     // and set any deduced parameter packs to an empty argument pack.
     // The latter part of this is a (minor) correctness issue.
 
-    // Save the deduced template arguments for each parameter pack expanded
-    // by this pack expansion, then clear out the deduction.
-    SmallVector<DeducedTemplateArgument, 2>
-      SavedPacks(PackIndices.size());
-    NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
-    PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
-                                 NewlyDeducedPacks);
+    // Prepare to deduce the packs within the pattern.
+    PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
 
     // Keep track of the deduced template arguments for each parameter pack
     // expanded by this pack expansion (the outer index) and for each
     // template argument (the inner SmallVectors).
     bool HasAnyArguments = false;
-    while (hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs)) {
+    for (; hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs); ++ArgIdx) {
       HasAnyArguments = true;
 
       // Deduce template arguments from the pattern.
@@ -1895,26 +1921,12 @@
                                       Info, Deduced))
         return Result;
 
-      // Capture the deduced template arguments for each parameter pack expanded
-      // by this pack expansion, add them to the list of arguments we've deduced
-      // for that pack, then clear out the deduced argument.
-      for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-        DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
-        if (!DeducedArg.isNull()) {
-          NewlyDeducedPacks[I].push_back(DeducedArg);
-          DeducedArg = DeducedTemplateArgument();
-        }
-      }
-
-      ++ArgIdx;
+      PackScope.nextPackElement();
     }
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (Sema::TemplateDeductionResult Result
-          = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
-                                        Deduced, PackIndices, SavedPacks,
-                                        NewlyDeducedPacks, Info))
+    if (auto Result = PackScope.finish(HasAnyArguments))
       return Result;
   }
 
@@ -2020,21 +2032,21 @@
   case TemplateArgument::Declaration: {
     Expr *E
       = S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
-          .takeAs<Expr>();
+          .getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(E), E);
   }
 
   case TemplateArgument::NullPtr: {
     Expr *E
       = S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
-          .takeAs<Expr>();
+          .getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true),
                                E);
   }
 
   case TemplateArgument::Integral: {
     Expr *E
-      = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).takeAs<Expr>();
+      = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(E), E);
   }
 
@@ -2804,9 +2816,19 @@
         // argument, because it was explicitly-specified. Just record the
         // presence of this argument.
         Builder.push_back(Deduced[I]);
+        // We may have had explicitly-specified template arguments for a
+        // template parameter pack (that may or may not have been extended
+        // via additional deduced arguments).
+        if (Param->isParameterPack() && CurrentInstantiationScope) {
+          if (CurrentInstantiationScope->getPartiallySubstitutedPack() ==
+              Param) {
+            // Forget the partially-substituted pack; its substitution is now
+            // complete.
+            CurrentInstantiationScope->ResetPartiallySubstitutedPack();
+          }
+        }
         continue;
       }
-
       // We have deduced this argument, so it still needs to be
       // checked and converted.
 
@@ -3403,30 +3425,9 @@
       break;
 
     QualType ParamPattern = ParamExpansion->getPattern();
-    SmallVector<unsigned, 2> PackIndices;
-    {
-      llvm::SmallBitVector SawIndices(TemplateParams->size());
-      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      collectUnexpandedParameterPacks(ParamPattern, Unexpanded);
-      for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
-        unsigned Depth, Index;
-        std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
-        if (Depth == 0 && !SawIndices[Index]) {
-          SawIndices[Index] = true;
-          PackIndices.push_back(Index);
-        }
-      }
-    }
-    assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
+    PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,
+                                 ParamPattern);
 
-    // Keep track of the deduced template arguments for each parameter pack
-    // expanded by this pack expansion (the outer index) and for each
-    // template argument (the inner SmallVectors).
-    NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
-    SmallVector<DeducedTemplateArgument, 2>
-      SavedPacks(PackIndices.size());
-    PrepareArgumentPackDeduction(*this, Deduced, PackIndices, SavedPacks,
-                                 NewlyDeducedPacks);
     bool HasAnyArguments = false;
     for (; ArgIdx < Args.size(); ++ArgIdx) {
       HasAnyArguments = true;
@@ -3435,7 +3436,7 @@
       ParamType = OrigParamType;
       Expr *Arg = Args[ArgIdx];
       QualType ArgType = Arg->getType();
-      
+
       unsigned TDF = 0;
       if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
                                                     ParamType, ArgType, Arg,
@@ -3476,24 +3477,12 @@
           return Result;
       }
 
-      // Capture the deduced template arguments for each parameter pack expanded
-      // by this pack expansion, add them to the list of arguments we've deduced
-      // for that pack, then clear out the deduced argument.
-      for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-        DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
-        if (!DeducedArg.isNull()) {
-          NewlyDeducedPacks[I].push_back(DeducedArg);
-          DeducedArg = DeducedTemplateArgument();
-        }
-      }
+      PackScope.nextPackElement();
     }
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (Sema::TemplateDeductionResult Result
-          = FinishArgumentPackDeduction(*this, TemplateParams, HasAnyArguments,
-                                        Deduced, PackIndices, SavedPacks,
-                                        NewlyDeducedPacks, Info))
+    if (auto Result = PackScope.finish(HasAnyArguments))
       return Result;
 
     // After we've matching against a parameter pack, we're done.
@@ -3982,7 +3971,7 @@
     ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
     if (NonPlaceholder.isInvalid())
       return DAR_FailedAlreadyDiagnosed;
-    Init = NonPlaceholder.take();
+    Init = NonPlaceholder.get();
   }
 
   if (Init->isTypeDependent() || Type.getType()->isDependentType()) {
@@ -4199,34 +4188,24 @@
     // otherwise, the ordering rules for static functions against non-static
     // functions don't make any sense.
     //
-    // C++98/03 doesn't have this provision, so instead we drop the
-    // first argument of the free function, which seems to match
-    // existing practice.
+    // C++98/03 doesn't have this provision but we've extended DR532 to cover
+    // it as wording was broken prior to it.
     SmallVector<QualType, 4> Args1;
 
-    unsigned Skip1 = 0, Skip2 = 0;
     unsigned NumComparedArguments = NumCallArguments1;
 
     if (!Method2 && Method1 && !Method1->isStatic()) {
-      if (S.getLangOpts().CPlusPlus11) {
-        // Compare 'this' from Method1 against first parameter from Method2.
-        AddImplicitObjectParameterType(S.Context, Method1, Args1);
-        ++NumComparedArguments;
-      } else
-        // Ignore first parameter from Method2.
-        ++Skip2;
+      // Compare 'this' from Method1 against first parameter from Method2.
+      AddImplicitObjectParameterType(S.Context, Method1, Args1);
+      ++NumComparedArguments;
     } else if (!Method1 && Method2 && !Method2->isStatic()) {
-      if (S.getLangOpts().CPlusPlus11)
-        // Compare 'this' from Method2 against first parameter from Method1.
-        AddImplicitObjectParameterType(S.Context, Method2, Args2);
-      else
-        // Ignore first parameter from Method1.
-        ++Skip1;
+      // Compare 'this' from Method2 against first parameter from Method1.
+      AddImplicitObjectParameterType(S.Context, Method2, Args2);
     }
 
-    Args1.insert(Args1.end(), Proto1->param_type_begin() + Skip1,
+    Args1.insert(Args1.end(), Proto1->param_type_begin(),
                  Proto1->param_type_end());
-    Args2.insert(Args2.end(), Proto2->param_type_begin() + Skip2,
+    Args2.insert(Args2.end(), Proto2->param_type_begin(),
                  Proto2->param_type_end());
 
     // C++ [temp.func.order]p5:
@@ -4240,7 +4219,7 @@
                                 Args1.data(), Args1.size(), Info, Deduced,
                                 TDF_None, /*PartialOrdering=*/true,
                                 RefParamComparisons))
-        return false;
+      return false;
 
     break;
   }
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index fae1222..14c6405 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1084,7 +1084,7 @@
 ExprResult 
 TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
   if (!E->isTypeDependent())
-    return SemaRef.Owned(E);
+    return E;
 
   return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
 }
@@ -1098,7 +1098,7 @@
   // arguments left unspecified.
   if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(),
                                         NTTP->getPosition()))
-    return SemaRef.Owned(E);
+    return E;
 
   TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
   if (NTTP->isParameterPack()) {
@@ -1138,7 +1138,7 @@
   // case we just return that expression.
   if (arg.getKind() == TemplateArgument::Expression) {
     Expr *argExpr = arg.getAsExpr();
-    result = SemaRef.Owned(argExpr);
+    result = argExpr;
     type = argExpr->getType();
 
   } else if (arg.getKind() == TemplateArgument::Declaration ||
@@ -1185,11 +1185,9 @@
   }
   if (result.isInvalid()) return ExprError();
 
-  Expr *resultExpr = result.take();
-  return SemaRef.Owned(new (SemaRef.Context)
-                SubstNonTypeTemplateParmExpr(type,
-                                             resultExpr->getValueKind(),
-                                             loc, parm, resultExpr));
+  Expr *resultExpr = result.get();
+  return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
+      type, resultExpr->getValueKind(), loc, parm, resultExpr);
 }
                                                    
 ExprResult 
@@ -1197,7 +1195,7 @@
                                           SubstNonTypeTemplateParmPackExpr *E) {
   if (getSema().ArgumentPackSubstitutionIndex == -1) {
     // We aren't expanding the parameter pack, so just return ourselves.
-    return getSema().Owned(E);
+    return E;
   }
 
   TemplateArgument Arg = E->getArgumentPack();
@@ -1850,7 +1848,7 @@
     S.Diag(PointOfInstantiation,
            diag::err_implicit_instantiate_member_undefined)
       << S.Context.getTypeDeclType(Instantiation);
-    S.Diag(Pattern->getLocation(), diag::note_member_of_template_here);
+    S.Diag(Pattern->getLocation(), diag::note_member_declared_at);
   } else {
     S.Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
       << (TSK != TSK_ImplicitInstantiation)
@@ -2035,11 +2033,11 @@
       ActOnStartCXXInClassMemberInitializer();
       ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
                                             /*CXXDirectInit=*/false);
-      Expr *Init = NewInit.take();
+      Expr *Init = NewInit.get();
       assert((!Init || !isa<ParenListExpr>(Init)) &&
              "call-style init in class");
-      ActOnFinishCXXInClassMemberInitializer(NewField, Init->getLocStart(),
-                                             Init);
+      ActOnFinishCXXInClassMemberInitializer(NewField,
+        Init ? Init->getLocStart() : SourceLocation(), Init);
     }
   }
   // Instantiate late parsed attributes, and attach them to their decls.
@@ -2571,7 +2569,7 @@
 StmtResult
 Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (!S)
-    return Owned(S);
+    return S;
 
   TemplateInstantiator Instantiator(*this, TemplateArgs,
                                     SourceLocation(),
@@ -2582,7 +2580,7 @@
 ExprResult
 Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (!E)
-    return Owned(E);
+    return E;
 
   TemplateInstantiator Instantiator(*this, TemplateArgs,
                                     SourceLocation(),
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index be2db41..c655d3f 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -79,7 +79,7 @@
     EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated);
     ExprResult Result = S.SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs);
     if (!Result.isInvalid())
-      S.AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>(),
+      S.AddAlignedAttr(Aligned->getLocation(), New, Result.getAs<Expr>(),
                        Aligned->getSpellingListIndex(), IsPackExpansion);
   } else {
     TypeSourceInfo *Result = S.SubstType(Aligned->getAlignmentType(),
@@ -138,13 +138,13 @@
     ExprResult Result = S.SubstExpr(A->getCond(), TemplateArgs);
     if (Result.isInvalid())
       return;
-    Cond = Result.takeAs<Expr>();
+    Cond = Result.getAs<Expr>();
   }
   if (A->getCond()->isTypeDependent() && !Cond->isTypeDependent()) {
     ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
     if (Converted.isInvalid())
       return;
-    Cond = Converted.take();
+    Cond = Converted.get();
   }
 
   SmallVector<PartialDiagnosticAt, 8> Diags;
@@ -475,7 +475,7 @@
       Invalid = true;
       BitWidth = nullptr;
     } else
-      BitWidth = InstantiatedBitWidth.takeAs<Expr>();
+      BitWidth = InstantiatedBitWidth.getAs<Expr>();
   }
 
   FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(),
@@ -741,7 +741,7 @@
   EnumConstantDecl *LastEnumConst = nullptr;
   for (auto *EC : Pattern->enumerators()) {
     // The specified value for the enumerator.
-    ExprResult Value = SemaRef.Owned((Expr *)nullptr);
+    ExprResult Value((Expr *)nullptr);
     if (Expr *UninstValue = EC->getInitExpr()) {
       // The enumerator's value expression is a constant expression.
       EnterExpressionEvaluationContext Unevaluated(SemaRef,
@@ -753,7 +753,7 @@
     // Drop the initial value and continue.
     bool isInvalid = false;
     if (Value.isInvalid()) {
-      Value = SemaRef.Owned((Expr *)nullptr);
+      Value = nullptr;
       isInvalid = true;
     }
 
@@ -1230,8 +1230,7 @@
 
     void *InsertPos = nullptr;
     FunctionDecl *SpecFunc
-      = FunctionTemplate->findSpecialization(Innermost.begin(), Innermost.size(),
-                                             InsertPos);
+      = FunctionTemplate->findSpecialization(Innermost, InsertPos);
 
     // If we already have a function template specialization, return it.
     if (SpecFunc)
@@ -1508,9 +1507,7 @@
 
     void *InsertPos = nullptr;
     FunctionDecl *SpecFunc
-      = FunctionTemplate->findSpecialization(Innermost.begin(), 
-                                             Innermost.size(),
-                                             InsertPos);
+      = FunctionTemplate->findSpecialization(Innermost, InsertPos);
 
     // If we already have a function template specialization, return it.
     if (SpecFunc)
@@ -2311,7 +2308,7 @@
                                      OMPThreadPrivateDecl *D) {
   SmallVector<Expr *, 5> Vars;
   for (auto *I : D->varlists()) {
-    Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).take();
+    Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get();
     assert(isa<DeclRefExpr>(Var) && "threadprivate arg is not a DeclRefExpr");
     Vars.push_back(Var);
   }
@@ -2386,8 +2383,7 @@
   // in the member template's set of class template explicit specializations.
   void *InsertPos = nullptr;
   ClassTemplateSpecializationDecl *PrevDecl =
-      InstClassTemplate->findSpecialization(Converted.data(), Converted.size(),
-                                            InsertPos);
+      InstClassTemplate->findSpecialization(Converted, InsertPos);
 
   // Check whether we've already seen a conflicting instantiation of this
   // declaration (for instance, if there was a prior implicit instantiation).
@@ -2509,7 +2505,7 @@
   // corresponds to these arguments.
   void *InsertPos = nullptr;
   if (VarTemplateSpecializationDecl *VarSpec = VarTemplate->findSpecialization(
-          Converted.data(), Converted.size(), InsertPos))
+          Converted, InsertPos))
     // If we already have a variable template specialization, return it.
     return VarSpec;
 
@@ -2520,7 +2516,7 @@
 Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
     VarTemplateDecl *VarTemplate, VarDecl *D, void *InsertPos,
     const TemplateArgumentListInfo &TemplateArgsInfo,
-    llvm::ArrayRef<TemplateArgument> Converted) {
+    ArrayRef<TemplateArgument> Converted) {
 
   // If this is the variable for an anonymous struct or union,
   // instantiate the anonymous struct/union type first.
@@ -2674,8 +2670,7 @@
   // in the member template's set of class template partial specializations.
   void *InsertPos = nullptr;
   ClassTemplateSpecializationDecl *PrevDecl
-    = ClassTemplate->findPartialSpecialization(Converted.data(),
-                                               Converted.size(), InsertPos);
+    = ClassTemplate->findPartialSpecialization(Converted, InsertPos);
 
   // Build the canonical type that describes the converted template
   // arguments of the class template partial specialization.
@@ -2799,8 +2794,7 @@
   // in the member template's set of variable template partial specializations.
   void *InsertPos = nullptr;
   VarTemplateSpecializationDecl *PrevDecl =
-      VarTemplate->findPartialSpecialization(Converted.data(), Converted.size(),
-                                             InsertPos);
+      VarTemplate->findPartialSpecialization(Converted, InsertPos);
 
   // Build the canonical type that describes the converted template
   // arguments of the variable template partial specialization.
@@ -3127,13 +3121,13 @@
       E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart());
 
     if (E.isUsable()) {
-      NoexceptExpr = E.take();
+      NoexceptExpr = E.get();
       if (!NoexceptExpr->isTypeDependent() &&
           !NoexceptExpr->isValueDependent())
         NoexceptExpr
           = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr,
               nullptr, diag::err_noexcept_needs_constant_expression,
-              /*AllowFold*/ false).take();
+              /*AllowFold*/ false).get();
     }
   }
 
@@ -3377,8 +3371,16 @@
       !PatternDecl->getReturnType()->getContainedAutoType())
     return;
 
-  if (PatternDecl->isInlined())
-    Function->setImplicitlyInline();
+  if (PatternDecl->isInlined()) {
+    // Function, and all later redeclarations of it (from imported modules,
+    // for instance), are now implicitly inline.
+    for (auto *D = Function->getMostRecentDecl(); /**/;
+         D = D->getPreviousDecl()) {
+      D->setImplicitlyInline();
+      if (D == Function)
+        break;
+    }
+  }
 
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
   if (Inst.isInvalid())
@@ -3675,9 +3677,14 @@
                          OldVar->getInitStyle() == VarDecl::CallInit);
     if (!Init.isInvalid()) {
       bool TypeMayContainAuto = true;
-      if (Init.get()) {
+      Expr *InitExpr = Init.get();
+
+      if (Var->hasAttr<DLLImportAttr>() && InitExpr &&
+          !InitExpr->isConstantInitializer(getASTContext(), false)) {
+        // Do not dynamically initialize dllimport variables.
+      } else if (InitExpr) {
         bool DirectInit = OldVar->isDirectInit();
-        AddInitializerToDecl(Var, Init.take(), DirectInit, TypeMayContainAuto);
+        AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto);
       } else
         ActOnUninitializedDecl(Var, TypeMayContainAuto);
     } else {
@@ -4056,7 +4063,7 @@
 
         // Build the initializer.
         MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(),
-                                                     BaseTInfo, TempInit.take(),
+                                                     BaseTInfo, TempInit.get(),
                                                      New->getParent(),
                                                      SourceLocation());
         if (NewInit.isInvalid()) {
@@ -4091,10 +4098,10 @@
       }
 
       if (Init->isBaseInitializer())
-        NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.take(),
+        NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.get(),
                                        New->getParent(), EllipsisLoc);
       else
-        NewInit = BuildDelegatingInitializer(TInfo, TempInit.take(),
+        NewInit = BuildDelegatingInitializer(TInfo, TempInit.get(),
                                   cast<CXXRecordDecl>(CurContext->getParent()));
     } else if (Init->isMemberInitializer()) {
       FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl(
@@ -4107,7 +4114,7 @@
         continue;
       }
 
-      NewInit = BuildMemberInitializer(Member, TempInit.take(),
+      NewInit = BuildMemberInitializer(Member, TempInit.get(),
                                        Init->getSourceLocation());
     } else if (Init->isIndirectMemberInitializer()) {
       IndirectFieldDecl *IndirectMember =
@@ -4121,7 +4128,7 @@
         continue;
       }
 
-      NewInit = BuildMemberInitializer(IndirectMember, TempInit.take(),
+      NewInit = BuildMemberInitializer(IndirectMember, TempInit.get(),
                                        Init->getSourceLocation());
     }
 
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 9480c11..8e4ce0d 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -509,8 +509,8 @@
   }
   
   // Create the pack expansion expression and source-location information.
-  return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
-                                               EllipsisLoc, NumExpansions));
+  return new (Context)
+    PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
 }
 
 /// \brief Retrieve the depth and index of a parameter pack.
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index dec2b17..be1191c 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1566,7 +1566,7 @@
   if (ArraySize && ArraySize->hasPlaceholderType()) {
     ExprResult Result = CheckPlaceholderExpr(ArraySize);
     if (Result.isInvalid()) return QualType();
-    ArraySize = Result.take();
+    ArraySize = Result.get();
   }
 
   // Do lvalue-to-rvalue conversions on the array size expression.
@@ -1575,7 +1575,7 @@
     if (Result.isInvalid())
       return QualType();
 
-    ArraySize = Result.take();
+    ArraySize = Result.get();
   }
 
   // C99 6.7.5.2p1: The size expression shall have integer type.
@@ -1763,7 +1763,7 @@
 }
 
 QualType Sema::BuildFunctionType(QualType T,
-                                 llvm::MutableArrayRef<QualType> ParamTypes,
+                                 MutableArrayRef<QualType> ParamTypes,
                                  SourceLocation Loc, DeclarationName Entity,
                                  const FunctionProtoType::ExtProtoInfo &EPI) {
   bool Invalid = false;
@@ -1989,18 +1989,15 @@
   // TODO: mark whether we did this inference?
 }
 
-static void diagnoseIgnoredQualifiers(
-    Sema &S, unsigned Quals,
-    SourceLocation FallbackLoc,
-    SourceLocation ConstQualLoc = SourceLocation(),
-    SourceLocation VolatileQualLoc = SourceLocation(),
-    SourceLocation RestrictQualLoc = SourceLocation(),
-    SourceLocation AtomicQualLoc = SourceLocation()) {
+void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
+                                     SourceLocation FallbackLoc,
+                                     SourceLocation ConstQualLoc,
+                                     SourceLocation VolatileQualLoc,
+                                     SourceLocation RestrictQualLoc,
+                                     SourceLocation AtomicQualLoc) {
   if (!Quals)
     return;
 
-  const SourceManager &SM = S.getSourceManager();
-
   struct Qual {
     unsigned Mask;
     const char *Name;
@@ -2027,7 +2024,8 @@
       SourceLocation QualLoc = QualKinds[I].Loc;
       if (!QualLoc.isInvalid()) {
         FixIts[NumQuals] = FixItHint::CreateRemoval(QualLoc);
-        if (Loc.isInvalid() || SM.isBeforeInTranslationUnit(QualLoc, Loc))
+        if (Loc.isInvalid() ||
+            getSourceManager().isBeforeInTranslationUnit(QualLoc, Loc))
           Loc = QualLoc;
       }
 
@@ -2035,19 +2033,20 @@
     }
   }
 
-  S.Diag(Loc.isInvalid() ? FallbackLoc : Loc, diag::warn_qual_return_type)
+  Diag(Loc.isInvalid() ? FallbackLoc : Loc, DiagID)
     << QualStr << NumQuals << FixIts[0] << FixIts[1] << FixIts[2] << FixIts[3];
 }
 
 // Diagnose pointless type qualifiers on the return type of a function.
-static void diagnoseIgnoredFunctionQualifiers(Sema &S, QualType RetTy,
-                                              Declarator &D,
-                                              unsigned FunctionChunkIndex) {
+static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
+                                                  Declarator &D,
+                                                  unsigned FunctionChunkIndex) {
   if (D.getTypeObject(FunctionChunkIndex).Fun.hasTrailingReturnType()) {
     // FIXME: TypeSourceInfo doesn't preserve location information for
     // qualifiers.
-    diagnoseIgnoredQualifiers(S, RetTy.getLocalCVRQualifiers(),
-                              D.getIdentifierLoc());
+    S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+                                RetTy.getLocalCVRQualifiers(),
+                                D.getIdentifierLoc());
     return;
   }
 
@@ -2061,8 +2060,9 @@
 
     case DeclaratorChunk::Pointer: {
       DeclaratorChunk::PointerTypeInfo &PTI = OuterChunk.Ptr;
-      diagnoseIgnoredQualifiers(
-          S, PTI.TypeQuals,
+      S.diagnoseIgnoredQualifiers(
+          diag::warn_qual_return_type,
+          PTI.TypeQuals,
           SourceLocation(),
           SourceLocation::getFromRawEncoding(PTI.ConstQualLoc),
           SourceLocation::getFromRawEncoding(PTI.VolatileQualLoc),
@@ -2079,8 +2079,9 @@
       // FIXME: We can't currently provide an accurate source location and a
       // fix-it hint for these.
       unsigned AtomicQual = RetTy->isAtomicType() ? DeclSpec::TQ_atomic : 0;
-      diagnoseIgnoredQualifiers(S, RetTy.getCVRQualifiers() | AtomicQual,
-                                D.getIdentifierLoc());
+      S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+                                  RetTy.getCVRQualifiers() | AtomicQual,
+                                  D.getIdentifierLoc());
       return;
     }
 
@@ -2095,12 +2096,13 @@
 
   // Just parens all the way out to the decl specifiers. Diagnose any qualifiers
   // which are present there.
-  diagnoseIgnoredQualifiers(S, D.getDeclSpec().getTypeQualifiers(),
-                            D.getIdentifierLoc(),
-                            D.getDeclSpec().getConstSpecLoc(),
-                            D.getDeclSpec().getVolatileSpecLoc(),
-                            D.getDeclSpec().getRestrictSpecLoc(),
-                            D.getDeclSpec().getAtomicSpecLoc());
+  S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+                              D.getDeclSpec().getTypeQualifiers(),
+                              D.getIdentifierLoc(),
+                              D.getDeclSpec().getConstSpecLoc(),
+                              D.getDeclSpec().getVolatileSpecLoc(),
+                              D.getDeclSpec().getRestrictSpecLoc(),
+                              D.getDeclSpec().getAtomicSpecLoc());
 }
 
 static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
@@ -2393,9 +2395,9 @@
   }
 
   if (FTI.NumParams > 0) {
-    // For a declaration with parameters, eg. "T var(T());", suggest adding parens
-    // around the first parameter to turn the declaration into a variable
-    // declaration.
+    // For a declaration with parameters, eg. "T var(T());", suggest adding
+    // parens around the first parameter to turn the declaration into a
+    // variable declaration.
     SourceRange Range = FTI.Params[0].Param->getSourceRange();
     SourceLocation B = Range.getBegin();
     SourceLocation E = S.getLocForEndOfToken(Range.getEnd());
@@ -2405,8 +2407,8 @@
       << FixItHint::CreateInsertion(B, "(")
       << FixItHint::CreateInsertion(E, ")");
   } else {
-    // For a declaration without parameters, eg. "T var();", suggest replacing the
-    // parens with an initializer to turn the declaration into a variable
+    // For a declaration without parameters, eg. "T var();", suggest replacing
+    // the parens with an initializer to turn the declaration into a variable
     // declaration.
     const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
 
@@ -2788,7 +2790,7 @@
       if ((T.getCVRQualifiers() || T->isAtomicType()) &&
           !(S.getLangOpts().CPlusPlus &&
             (T->isDependentType() || T->isRecordType())))
-        diagnoseIgnoredFunctionQualifiers(S, T, D, chunkIndex);
+        diagnoseRedundantReturnTypeQualifiers(S, T, D, chunkIndex);
 
       // Objective-C ARC ownership qualifiers are ignored on the function
       // return type (by type canonicalization). Complain if this attribute
@@ -5127,7 +5129,7 @@
       ED = NewED;
     if (ED->isFixed()) {
       // If the enum has a fixed underlying type, any declaration of it will do.
-      *Suggested = 0;
+      *Suggested = nullptr;
       for (auto *Redecl : ED->redecls()) {
         if (LookupResult::isVisible(S, Redecl))
           return true;
@@ -5147,6 +5149,45 @@
   return LookupResult::isVisible(S, D);
 }
 
+/// Locks in the inheritance model for the given class and all of its bases.
+static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {
+  RD = RD->getMostRecentDecl();
+  if (!RD->hasAttr<MSInheritanceAttr>()) {
+    MSInheritanceAttr::Spelling IM;
+
+    switch (S.MSPointerToMemberRepresentationMethod) {
+    case LangOptions::PPTMK_BestCase:
+      IM = RD->calculateInheritanceModel();
+      break;
+    case LangOptions::PPTMK_FullGeneralitySingleInheritance:
+      IM = MSInheritanceAttr::Keyword_single_inheritance;
+      break;
+    case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
+      IM = MSInheritanceAttr::Keyword_multiple_inheritance;
+      break;
+    case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
+      IM = MSInheritanceAttr::Keyword_unspecified_inheritance;
+      break;
+    }
+
+    RD->addAttr(MSInheritanceAttr::CreateImplicit(
+        S.getASTContext(), IM,
+        /*BestCase=*/S.MSPointerToMemberRepresentationMethod ==
+            LangOptions::PPTMK_BestCase,
+        S.ImplicitMSInheritanceAttrLoc.isValid()
+            ? S.ImplicitMSInheritanceAttrLoc
+            : RD->getSourceRange()));
+  }
+
+  if (RD->hasDefinition()) {
+    // Assign inheritance models to all of the base classes, because now we can
+    // form pointers to members of base classes without calling
+    // RequireCompleteType on the pointer to member of the base class type.
+    for (const CXXBaseSpecifier &BS : RD->bases())
+      assignInheritanceModel(S, BS.getType()->getAsCXXRecordDecl());
+  }
+}
+
 /// \brief The implementation of RequireCompleteType
 bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
                                    TypeDiagnoser &Diagnoser) {
@@ -5162,7 +5203,7 @@
   NamedDecl *Def = nullptr;
   if (!T->isIncompleteType(&Def)) {
     // If we know about the definition but it is not visible, complain.
-    NamedDecl *SuggestedDef = 0;
+    NamedDecl *SuggestedDef = nullptr;
     if (!Diagnoser.Suppressed && Def &&
         !hasVisibleDefinition(*this, Def, &SuggestedDef)) {
       // Suppress this error outside of a SFINAE context if we've already
@@ -5185,36 +5226,7 @@
       if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {
         if (!MPTy->getClass()->isDependentType()) {
           RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0);
-
-          CXXRecordDecl *RD = MPTy->getMostRecentCXXRecordDecl();
-          if (!RD->hasAttr<MSInheritanceAttr>()) {
-            MSInheritanceAttr::Spelling InheritanceModel;
-
-            switch (MSPointerToMemberRepresentationMethod) {
-            case LangOptions::PPTMK_BestCase:
-              InheritanceModel = RD->calculateInheritanceModel();
-              break;
-            case LangOptions::PPTMK_FullGeneralitySingleInheritance:
-              InheritanceModel = MSInheritanceAttr::Keyword_single_inheritance;
-              break;
-            case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
-              InheritanceModel =
-                  MSInheritanceAttr::Keyword_multiple_inheritance;
-              break;
-            case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
-              InheritanceModel =
-                  MSInheritanceAttr::Keyword_unspecified_inheritance;
-              break;
-            }
-
-            RD->addAttr(MSInheritanceAttr::CreateImplicit(
-                getASTContext(), InheritanceModel,
-                /*BestCase=*/MSPointerToMemberRepresentationMethod ==
-                    LangOptions::PPTMK_BestCase,
-                ImplicitMSInheritanceAttrLoc.isValid()
-                    ? ImplicitMSInheritanceAttrLoc
-                    : RD->getSourceRange()));
-          }
+          assignInheritanceModel(*this, MPTy->getMostRecentCXXRecordDecl());
         }
       }
     }
@@ -5461,7 +5473,7 @@
 QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) {
   ExprResult ER = CheckPlaceholderExpr(E);
   if (ER.isInvalid()) return QualType();
-  E = ER.take();
+  E = ER.get();
 
   if (!E->isTypeDependent()) {
     QualType T = E->getType();
@@ -5541,7 +5553,7 @@
 QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc) {
   ExprResult ER = CheckPlaceholderExpr(E);
   if (ER.isInvalid()) return QualType();
-  E = ER.take();
+  E = ER.get();
 
   return Context.getDecltypeType(E, getDecltypeForExpr(*this, E));
 }
@@ -5557,12 +5569,23 @@
     } else {
       QualType Underlying = BaseType;
       if (!BaseType->isDependentType()) {
+        // The enum could be incomplete if we're parsing its definition or
+        // recovering from an error.
+        NamedDecl *FwdDecl = nullptr;
+        if (BaseType->isIncompleteType(&FwdDecl)) {
+          Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
+          Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
+          return QualType();
+        }
+
         EnumDecl *ED = BaseType->getAs<EnumType>()->getDecl();
         assert(ED && "EnumType has no EnumDecl");
+
         DiagnoseUseOfDecl(ED, Loc);
+
         Underlying = ED->getIntegerType();
+        assert(!Underlying.isNull());
       }
-      assert(!Underlying.isNull());
       return Context.getUnaryTransformType(BaseType, Underlying,
                                         UnaryTransformType::EnumUnderlyingType);
     }
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 3386b5b..5626ad5 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -604,8 +604,15 @@
   }
 
   ExprResult TransformAddressOfOperand(Expr *E);
+
   ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
-                                                bool IsAddressOfOperand);
+                                                bool IsAddressOfOperand,
+                                                TypeSourceInfo **RecoveryTSI);
+
+  ExprResult TransformParenDependentScopeDeclRefExpr(
+      ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
+      TypeSourceInfo **RecoveryTSI);
+
   StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
 
 // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
@@ -743,7 +750,7 @@
   /// By default, performs semantic analysis when building the function type.
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildFunctionProtoType(QualType T,
-                                    llvm::MutableArrayRef<QualType> ParamTypes,
+                                    MutableArrayRef<QualType> ParamTypes,
                                     const FunctionProtoType::ExtProtoInfo &EPI);
 
   /// \brief Build a new unprototyped function type.
@@ -1194,7 +1201,7 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildDeclStmt(llvm::MutableArrayRef<Decl *> Decls,
+  StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
                              SourceLocation StartLoc, SourceLocation EndLoc) {
     Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
     return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
@@ -1301,7 +1308,7 @@
 
   /// \brief Build a new OpenMP 'if' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPIfClause(Expr *Condition,
                                 SourceLocation StartLoc,
@@ -1313,7 +1320,7 @@
 
   /// \brief Build a new OpenMP 'num_threads' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
                                         SourceLocation StartLoc,
@@ -1325,7 +1332,7 @@
 
   /// \brief Build a new OpenMP 'safelen' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
                                      SourceLocation LParenLoc,
@@ -1335,7 +1342,7 @@
 
   /// \brief Build a new OpenMP 'collapse' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
                                       SourceLocation LParenLoc,
@@ -1346,7 +1353,7 @@
 
   /// \brief Build a new OpenMP 'default' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPDefaultClause(OpenMPDefaultClauseKind Kind,
                                      SourceLocation KindKwLoc,
@@ -1359,7 +1366,7 @@
 
   /// \brief Build a new OpenMP 'proc_bind' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPProcBindClause(OpenMPProcBindClauseKind Kind,
                                       SourceLocation KindKwLoc,
@@ -1370,9 +1377,24 @@
                                                StartLoc, LParenLoc, EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'schedule' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPScheduleClause(OpenMPScheduleClauseKind Kind,
+                                      Expr *ChunkSize,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation KindLoc,
+                                      SourceLocation CommaLoc,
+                                      SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPScheduleClause(
+        Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
+  }
+
   /// \brief Build a new OpenMP 'private' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
                                      SourceLocation StartLoc,
@@ -1384,7 +1406,7 @@
 
   /// \brief Build a new OpenMP 'firstprivate' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
                                           SourceLocation StartLoc,
@@ -1394,9 +1416,21 @@
                                                    EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'lastprivate' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc,
+                                                  EndLoc);
+  }
+
   /// \brief Build a new OpenMP 'shared' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
                                     SourceLocation StartLoc,
@@ -1406,10 +1440,26 @@
                                              EndLoc);
   }
 
-  /// \brief Build a new OpenMP 'linear' clause.
+  /// \brief Build a new OpenMP 'reduction' clause.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPReductionClause(ArrayRef<Expr *> VarList,
+                                       SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation ColonLoc,
+                                       SourceLocation EndLoc,
+                                       CXXScopeSpec &ReductionIdScopeSpec,
+                                       const DeclarationNameInfo &ReductionId) {
+    return getSema().ActOnOpenMPReductionClause(
+        VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
+        ReductionId);
+  }
+
+  /// \brief Build a new OpenMP 'linear' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
                                     SourceLocation StartLoc,
                                     SourceLocation LParenLoc,
@@ -1419,9 +1469,22 @@
                                              ColonLoc, EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'aligned' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation ColonLoc,
+                                     SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
+                                              LParenLoc, ColonLoc, EndLoc);
+  }
+
   /// \brief Build a new OpenMP 'copyin' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
                                     SourceLocation StartLoc,
@@ -1431,6 +1494,18 @@
                                              EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'copyprivate' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc,
+                                                  EndLoc);
+  }
+
   /// \brief Rebuild the operand to an Objective-C \@synchronized statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -1474,7 +1549,7 @@
     if (ForEachStmt.isInvalid())
       return StmtError();
 
-    return getSema().FinishObjCForCollectionStmt(ForEachStmt.take(), Body);
+    return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
   }
 
   /// \brief Build a new C++ exception declaration.
@@ -1729,25 +1804,25 @@
              "unnamed member not of record type?");
 
       BaseResult =
-        getSema().PerformObjectMemberConversion(BaseResult.take(),
+        getSema().PerformObjectMemberConversion(BaseResult.get(),
                                                 QualifierLoc.getNestedNameSpecifier(),
                                                 FoundDecl, Member);
       if (BaseResult.isInvalid())
         return ExprError();
-      Base = BaseResult.take();
+      Base = BaseResult.get();
       ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind();
       MemberExpr *ME =
         new (getSema().Context) MemberExpr(Base, isArrow,
                                            Member, MemberNameInfo,
                                            cast<FieldDecl>(Member)->getType(),
                                            VK, OK_Ordinary);
-      return getSema().Owned(ME);
+      return ME;
     }
 
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
 
-    Base = BaseResult.take();
+    Base = BaseResult.get();
     QualType BaseType = Base->getType();
 
     // FIXME: this involves duplicating earlier analysis in a lot of
@@ -1872,7 +1947,7 @@
   /// any semantic analysis. Subclasses may override this routine to provide
   /// different behavior.
   ExprResult RebuildImplicitValueInitExpr(QualType T) {
-    return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
+    return new (SemaRef.Context) ImplicitValueInitExpr(T);
   }
 
   /// \brief Build a new \c va_arg expression.
@@ -2137,9 +2212,7 @@
                                 QualType ThisType,
                                 bool isImplicit) {
     getSema().CheckCXXThisCapture(ThisLoc);
-    return getSema().Owned(
-                      new (getSema().Context) CXXThisExpr(ThisLoc, ThisType,
-                                                          isImplicit));
+    return new (getSema().Context) CXXThisExpr(ThisLoc, ThisType, isImplicit);
   }
 
   /// \brief Build a new C++ throw expression.
@@ -2158,8 +2231,7 @@
   /// provide different behavior.
   ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc,
                                             ParmVarDecl *Param) {
-    return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
-                                                     Param));
+    return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param);
   }
 
   /// \brief Build a new C++11 default-initialization expression.
@@ -2169,8 +2241,7 @@
   /// routine to provide different behavior.
   ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
                                        FieldDecl *Field) {
-    return getSema().Owned(CXXDefaultInitExpr::Create(getSema().Context, Loc,
-                                                      Field));
+    return CXXDefaultInitExpr::Create(getSema().Context, Loc, Field);
   }
 
   /// \brief Build a new C++ zero-initialization expression.
@@ -2267,16 +2338,17 @@
                                           SourceLocation TemplateKWLoc,
                                        const DeclarationNameInfo &NameInfo,
                               const TemplateArgumentListInfo *TemplateArgs,
-                                          bool IsAddressOfOperand) {
+                                          bool IsAddressOfOperand,
+                                          TypeSourceInfo **RecoveryTSI) {
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
 
     if (TemplateArgs || TemplateKWLoc.isValid())
-      return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc,
-                                                    NameInfo, TemplateArgs);
+      return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
+                                                    TemplateArgs);
 
-    return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo,
-                                                       IsAddressOfOperand);
+    return getSema().BuildQualifiedDeclarationNameExpr(
+        SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
   }
 
   /// \brief Build a new template-id expression.
@@ -2459,8 +2531,7 @@
   ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
                                          TypeSourceInfo *EncodeTypeInfo,
                                          SourceLocation RParenLoc) {
-    return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
-                                                           RParenLoc));
+    return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc);
   }
 
   /// \brief Build a new Objective-C class message.
@@ -2502,24 +2573,12 @@
                                           bool IsArrow, bool IsFreeIvar) {
     // FIXME: We lose track of the IsFreeIvar bit.
     CXXScopeSpec SS;
-    ExprResult Base = getSema().Owned(BaseArg);
-    LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
-                   Sema::LookupMemberName);
-    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
-                                                         /*FIME:*/IvarLoc,
-                                                         SS, nullptr,
-                                                         false);
-    if (Result.isInvalid() || Base.isInvalid())
-      return ExprError();
-
-    if (Result.get())
-      return Result;
-
-    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
+    DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
+    return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
                                               /*FIXME:*/IvarLoc, IsArrow,
                                               SS, SourceLocation(),
                                               /*FirstQualifierInScope=*/nullptr,
-                                              R,
+                                              NameInfo,
                                               /*TemplateArgs=*/nullptr);
   }
 
@@ -2531,24 +2590,14 @@
                                         ObjCPropertyDecl *Property,
                                         SourceLocation PropertyLoc) {
     CXXScopeSpec SS;
-    ExprResult Base = getSema().Owned(BaseArg);
-    LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
-                   Sema::LookupMemberName);
-    bool IsArrow = false;
-    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
-                                                         /*FIME:*/PropertyLoc,
-                                                         SS, nullptr, false);
-    if (Result.isInvalid() || Base.isInvalid())
-      return ExprError();
-
-    if (Result.get())
-      return Result;
-
-    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
-                                              /*FIXME:*/PropertyLoc, IsArrow,
+    DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
+    return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
+                                              /*FIXME:*/PropertyLoc,
+                                              /*IsArrow=*/false,
                                               SS, SourceLocation(),
                                               /*FirstQualifierInScope=*/nullptr,
-                                              R, /*TemplateArgs=*/nullptr);
+                                              NameInfo,
+                                              /*TemplateArgs=*/nullptr);
   }
 
   /// \brief Build a new Objective-C property reference expression.
@@ -2572,26 +2621,14 @@
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
-                                SourceLocation OpLoc,
-                                      bool IsArrow) {
+                                SourceLocation OpLoc, bool IsArrow) {
     CXXScopeSpec SS;
-    ExprResult Base = getSema().Owned(BaseArg);
-    LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
-                   Sema::LookupMemberName);
-    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
-                                                         OpLoc,
-                                                         SS, nullptr, false);
-    if (Result.isInvalid() || Base.isInvalid())
-      return ExprError();
-
-    if (Result.get())
-      return Result;
-
-    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
+    DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
+    return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
                                               OpLoc, IsArrow,
                                               SS, SourceLocation(),
                                               /*FirstQualifierInScope=*/nullptr,
-                                              R,
+                                              NameInfo,
                                               /*TemplateArgs=*/nullptr);
   }
 
@@ -2616,15 +2653,15 @@
                                                   VK_RValue, BuiltinLoc);
     QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
     Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
-                                       CK_BuiltinFnToFnPtr).take();
+                                       CK_BuiltinFnToFnPtr).get();
 
     // Build the CallExpr
-    ExprResult TheCall = SemaRef.Owned(new (SemaRef.Context) CallExpr(
+    ExprResult TheCall = new (SemaRef.Context) CallExpr(
         SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
-        Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc));
+        Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc);
 
     // Type-check the __builtin_shufflevector expression.
-    return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.take()));
+    return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
   }
 
   /// \brief Build a new convert vector expression.
@@ -2728,7 +2765,7 @@
 template<typename Derived>
 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
   if (!S)
-    return SemaRef.Owned(S);
+    return S;
 
   switch (S->getStmtClass()) {
   case Stmt::NoStmtClass: break;
@@ -2754,7 +2791,7 @@
     }
   }
 
-  return SemaRef.Owned(S);
+  return S;
 }
 
 template<typename Derived>
@@ -2778,7 +2815,7 @@
 template<typename Derived>
 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
   if (!E)
-    return SemaRef.Owned(E);
+    return E;
 
   switch (E->getStmtClass()) {
     case Stmt::NoStmtClass: break;
@@ -2789,7 +2826,7 @@
 #include "clang/AST/StmtNodes.inc"
   }
 
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -2798,7 +2835,7 @@
   // Initializers are instantiated like expressions, except that various outer
   // layers are stripped.
   if (!Init)
-    return SemaRef.Owned(Init);
+    return Init;
 
   if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
     Init = ExprTemp->getSubExpr();
@@ -2926,9 +2963,11 @@
         if (Out.isInvalid())
           return true;
 
+        // FIXME: Can this happen? We should not try to expand the pack
+        // in this case.
         if (Out.get()->containsUnexpandedParameterPack()) {
-          Out = RebuildPackExpansion(Out.get(), Expansion->getEllipsisLoc(),
-                                     OrigNumExpansions);
+          Out = getDerived().RebuildPackExpansion(
+              Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
           if (Out.isInvalid())
             return true;
         }
@@ -2936,6 +2975,23 @@
         Outputs.push_back(Out.get());
       }
 
+      // If we're supposed to retain a pack expansion, do so by temporarily
+      // forgetting the partially-substituted parameter pack.
+      if (RetainExpansion) {
+        ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+
+        ExprResult Out = getDerived().TransformExpr(Pattern);
+        if (Out.isInvalid())
+          return true;
+
+        Out = getDerived().RebuildPackExpansion(
+            Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
+        if (Out.isInvalid())
+          return true;
+
+        Outputs.push_back(Out.get());
+      }
+
       continue;
     }
 
@@ -3304,7 +3360,7 @@
     ExprResult E = getDerived().TransformExpr(InputExpr);
     E = SemaRef.ActOnConstantExpression(E);
     if (E.isInvalid()) return true;
-    Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
+    Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
     return false;
   }
   }
@@ -3951,8 +4007,8 @@
   if (Size) {
     EnterExpressionEvaluationContext Unevaluated(SemaRef,
                                                  Sema::ConstantEvaluated);
-    Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
-    Size = SemaRef.ActOnConstantExpression(Size).take();
+    Size = getDerived().TransformExpr(Size).template getAs<Expr>();
+    Size = SemaRef.ActOnConstantExpression(Size).get();
   }
   NewTL.setSizeExpr(Size);
 
@@ -4001,7 +4057,7 @@
   if (SizeResult.isInvalid())
     return QualType();
 
-  Expr *Size = SizeResult.take();
+  Expr *Size = SizeResult.get();
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
@@ -4099,7 +4155,7 @@
       ElementType != T->getElementType() ||
       Size.get() != T->getSizeExpr()) {
     Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
-                                                             Size.take(),
+                                                             Size.get(),
                                                          T->getAttributeLoc());
     if (Result.isNull())
       return QualType();
@@ -4588,7 +4644,7 @@
     if (Result.isNull())
       return QualType();
   }
-  else E.take();
+  else E.get();
 
   TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
   NewTL.setTypeofLoc(TL.getTypeofLoc());
@@ -4635,7 +4691,7 @@
   if (E.isInvalid())
     return QualType();
 
-  E = getSema().ActOnDecltypeExpression(E.take());
+  E = getSema().ActOnDecltypeExpression(E.get());
   if (E.isInvalid())
     return QualType();
 
@@ -4646,7 +4702,7 @@
     if (Result.isNull())
       return QualType();
   }
-  else E.take();
+  else E.get();
 
   DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
@@ -5313,7 +5369,7 @@
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
-  return SemaRef.Owned(S);
+  return S;
 }
 
 template<typename Derived>
@@ -5345,7 +5401,7 @@
     }
 
     SubStmtChanged = SubStmtChanged || Result.get() != B;
-    Statements.push_back(Result.takeAs<Stmt>());
+    Statements.push_back(Result.getAs<Stmt>());
   }
 
   if (SubStmtInvalid)
@@ -5353,7 +5409,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       !SubStmtChanged)
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
                                           Statements,
@@ -5481,7 +5537,7 @@
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -5500,7 +5556,7 @@
       ConditionVar == S->getConditionVariable() &&
       Then.get() == S->getThen() &&
       Else.get() == S->getElse())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
                                     Then.get(),
@@ -5576,7 +5632,7 @@
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -5611,7 +5667,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Cond.get() == S->getCond() &&
       Body.get() == S->getBody())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
                                     /*FIXME:*/S->getWhileLoc(), Cond.get(),
@@ -5655,7 +5711,7 @@
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -5678,7 +5734,7 @@
       FullCond.get() == S->getCond() &&
       Inc.get() == S->getInc() &&
       Body.get() == S->getBody())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
                                      Init.get(), FullCond, ConditionVar,
@@ -5704,11 +5760,11 @@
   ExprResult Target = getDerived().TransformExpr(S->getTarget());
   if (Target.isInvalid())
     return StmtError();
-  Target = SemaRef.MaybeCreateExprWithCleanups(Target.take());
+  Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
 
   if (!getDerived().AlwaysRebuild() &&
       Target.get() == S->getTarget())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
                                               Target.get());
@@ -5717,13 +5773,13 @@
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
-  return SemaRef.Owned(S);
+  return S;
 }
 
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
-  return SemaRef.Owned(S);
+  return S;
 }
 
 template<typename Derived>
@@ -5755,7 +5811,7 @@
   }
 
   if (!getDerived().AlwaysRebuild() && !DeclChanged)
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildDeclStmt(Decls, S->getStartLoc(), S->getEndLoc());
 }
@@ -5810,14 +5866,14 @@
   }
 
   if (!getDerived().AlwaysRebuild() && !ExprsChanged)
-    return SemaRef.Owned(S);
+    return S;
 
   // Go through the clobbers.
   for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
     Clobbers.push_back(S->getClobberStringLiteral(I));
 
   // No need to transform the asm string literal.
-  AsmString = SemaRef.Owned(S->getAsmString());
+  AsmString = S->getAsmString();
   return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
                                         S->isVolatile(), S->getNumOutputs(),
                                         S->getNumInputs(), Names.data(),
@@ -5842,7 +5898,7 @@
       HadError = true;
     } else {
       HadChange |= (Result.get() != SrcExprs[i]);
-      TransformedExprs.push_back(Result.take());
+      TransformedExprs.push_back(Result.get());
     }
   }
 
@@ -5874,7 +5930,7 @@
       return StmtError();
     if (Catch.get() != S->getCatchStmt(I))
       AnyCatchChanged = true;
-    CatchStmts.push_back(Catch.release());
+    CatchStmts.push_back(Catch.get());
   }
 
   // Transform the @finally statement (if present).
@@ -5890,7 +5946,7 @@
       TryBody.get() == S->getTryBody() &&
       !AnyCatchChanged &&
       Finally.get() == S->getFinallyStmt())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
@@ -5944,7 +6000,7 @@
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
       Body.get() == S->getFinallyBody())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
@@ -5963,7 +6019,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       Operand.get() == S->getThrowExpr())
-    return getSema().Owned(S);
+    return S;
 
   return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
 }
@@ -5991,7 +6047,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Object.get() == S->getSynchExpr() &&
       Body.get() == S->getSynchBody())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
@@ -6010,7 +6066,7 @@
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
       Body.get() == S->getSubStmt())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCAutoreleasePoolStmt(
@@ -6041,7 +6097,7 @@
       Element.get() == S->getElement() &&
       Collection.get() == S->getCollection() &&
       Body.get() == S->getBody())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
@@ -6075,7 +6131,7 @@
 
   if (!getDerived().AlwaysRebuild() && !Var &&
       Handler.get() == S->getHandlerBlock())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
 }
@@ -6096,12 +6152,12 @@
       return StmtError();
 
     HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
-    Handlers.push_back(Handler.takeAs<Stmt>());
+    Handlers.push_back(Handler.getAs<Stmt>());
   }
 
   if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
       !HandlerChanged)
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
                                         Handlers);
@@ -6122,17 +6178,17 @@
   if (Cond.isInvalid())
     return StmtError();
   if (Cond.get())
-    Cond = SemaRef.CheckBooleanCondition(Cond.take(), S->getColonLoc());
+    Cond = SemaRef.CheckBooleanCondition(Cond.get(), S->getColonLoc());
   if (Cond.isInvalid())
     return StmtError();
   if (Cond.get())
-    Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.take());
+    Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
 
   ExprResult Inc = getDerived().TransformExpr(S->getInc());
   if (Inc.isInvalid())
     return StmtError();
   if (Inc.get())
-    Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.take());
+    Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
 
   StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
   if (LoopVar.isInvalid())
@@ -6171,7 +6227,7 @@
   }
 
   if (NewStmt.get() == S)
-    return SemaRef.Owned(S);
+    return S;
 
   return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
 }
@@ -6283,10 +6339,10 @@
 
   if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
       Handler.get() == S->getHandler())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
-                                        TryBlock.take(), Handler.take());
+                                        TryBlock.get(), Handler.get());
 }
 
 template <typename Derived>
@@ -6295,7 +6351,7 @@
   if (Block.isInvalid())
     return StmtError();
 
-  return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.take());
+  return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
 }
 
 template <typename Derived>
@@ -6308,8 +6364,8 @@
   if (Block.isInvalid())
     return StmtError();
 
-  return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.take(),
-                                           Block.take());
+  return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
+                                           Block.get());
 }
 
 template <typename Derived>
@@ -6322,8 +6378,16 @@
 
 template<typename Derived>
 StmtResult
-TreeTransform<Derived>::TransformOMPExecutableDirective(
-                                 OMPExecutableDirective *D) {
+TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
+  return S;
+}
+
+//===----------------------------------------------------------------------===//
+// OpenMP directive transformation
+//===----------------------------------------------------------------------===//
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
+    OMPExecutableDirective *D) {
 
   // Transform the clauses
   llvm::SmallVector<OMPClause *, 16> TClauses;
@@ -6333,12 +6397,9 @@
        I != E; ++I) {
     if (*I) {
       OMPClause *Clause = getDerived().TransformOMPClause(*I);
-      if (!Clause) {
-        return StmtError();
-      }
-      TClauses.push_back(Clause);
-    }
-    else {
+      if (Clause)
+        TClauses.push_back(Clause);
+    } else {
       TClauses.push_back(nullptr);
     }
   }
@@ -6346,58 +6407,124 @@
     return StmtError();
   }
   StmtResult AssociatedStmt =
-    getDerived().TransformStmt(D->getAssociatedStmt());
-  if (AssociatedStmt.isInvalid()) {
+      getDerived().TransformStmt(D->getAssociatedStmt());
+  if (AssociatedStmt.isInvalid() || TClauses.size() != Clauses.size()) {
     return StmtError();
   }
 
-  return getDerived().RebuildOMPExecutableDirective(D->getDirectiveKind(),
-                                                    TClauses,
-                                                    AssociatedStmt.take(),
-                                                    D->getLocStart(),
-                                                    D->getLocEnd());
+  return getDerived().RebuildOMPExecutableDirective(
+      D->getDirectiveKind(), TClauses, AssociatedStmt.get(), D->getLocStart(),
+      D->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
   DeclarationNameInfo DirName;
-  getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr);
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,
+                                             D->getLocStart());
   StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
   getDerived().getSema().EndOpenMPDSABlock(Res.get());
   return Res;
 }
 
-template<typename Derived>
+template <typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
   DeclarationNameInfo DirName;
-  getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr);
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,
+                                             D->getLocStart());
   StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
   getDerived().getSema().EndOpenMPDSABlock(Res.get());
   return Res;
 }
 
-template<typename Derived>
-OMPClause *
-TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
+    OMPParallelForDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName,
+                                             nullptr, D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
+    OMPParallelSectionsDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName,
+                                             nullptr, D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+//===----------------------------------------------------------------------===//
+// OpenMP clause transformation
+//===----------------------------------------------------------------------===//
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
   ExprResult Cond = getDerived().TransformExpr(C->getCondition());
   if (Cond.isInvalid())
     return nullptr;
-  return getDerived().RebuildOMPIfClause(Cond.take(), C->getLocStart(),
+  return getDerived().RebuildOMPIfClause(Cond.get(), C->getLocStart(),
                                          C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
   ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
   if (NumThreads.isInvalid())
     return nullptr;
-  return getDerived().RebuildOMPNumThreadsClause(NumThreads.take(),
-                                                 C->getLocStart(),
-                                                 C->getLParenLoc(),
-                                                 C->getLocEnd());
+  return getDerived().RebuildOMPNumThreadsClause(
+      NumThreads.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
 template <typename Derived>
@@ -6407,7 +6534,7 @@
   if (E.isInvalid())
     return nullptr;
   return getDerived().RebuildOMPSafelenClause(
-      E.take(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+      E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
 template <typename Derived>
@@ -6417,30 +6544,51 @@
   if (E.isInvalid())
     return 0;
   return getDerived().RebuildOMPCollapseClause(
-      E.take(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+      E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
-  return getDerived().RebuildOMPDefaultClause(C->getDefaultKind(),
-                                              C->getDefaultKindKwLoc(),
-                                              C->getLocStart(),
-                                              C->getLParenLoc(),
-                                              C->getLocEnd());
+  return getDerived().RebuildOMPDefaultClause(
+      C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getLocStart(),
+      C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
-  return getDerived().RebuildOMPProcBindClause(C->getProcBindKind(),
-                                               C->getProcBindKindKwLoc(),
-                                               C->getLocStart(),
-                                               C->getLParenLoc(),
-                                               C->getLocEnd());
+  return getDerived().RebuildOMPProcBindClause(
+      C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getLocStart(),
+      C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
+  ExprResult E = getDerived().TransformExpr(C->getChunkSize());
+  if (E.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPScheduleClause(
+      C->getScheduleKind(), E.get(), C->getLocStart(), C->getLParenLoc(),
+      C->getScheduleKindLoc(), C->getCommaLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
@@ -6449,33 +6597,43 @@
     ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
     if (EVar.isInvalid())
       return nullptr;
-    Vars.push_back(EVar.take());
+    Vars.push_back(EVar.get());
   }
-  return getDerived().RebuildOMPPrivateClause(Vars,
-                                              C->getLocStart(),
-                                              C->getLParenLoc(),
-                                              C->getLocEnd());
+  return getDerived().RebuildOMPPrivateClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
-OMPClause *
-TreeTransform<Derived>::TransformOMPFirstprivateClause(
-                                                 OMPFirstprivateClause *C) {
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
+    OMPFirstprivateClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
   Vars.reserve(C->varlist_size());
   for (auto *VE : C->varlists()) {
     ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
     if (EVar.isInvalid())
       return nullptr;
-    Vars.push_back(EVar.take());
+    Vars.push_back(EVar.get());
   }
-  return getDerived().RebuildOMPFirstprivateClause(Vars,
-                                                   C->getLocStart(),
-                                                   C->getLParenLoc(),
-                                                   C->getLocEnd());
+  return getDerived().RebuildOMPFirstprivateClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  return getDerived().RebuildOMPLastprivateClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
@@ -6484,15 +6642,38 @@
     ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
     if (EVar.isInvalid())
       return nullptr;
-    Vars.push_back(EVar.take());
+    Vars.push_back(EVar.get());
   }
-  return getDerived().RebuildOMPSharedClause(Vars,
-                                             C->getLocStart(),
-                                             C->getLParenLoc(),
-                                             C->getLocEnd());
+  return getDerived().RebuildOMPSharedClause(Vars, C->getLocStart(),
+                                             C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  CXXScopeSpec ReductionIdScopeSpec;
+  ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
+
+  DeclarationNameInfo NameInfo = C->getNameInfo();
+  if (NameInfo.getName()) {
+    NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
+    if (!NameInfo.getName())
+      return nullptr;
+  }
+  return getDerived().RebuildOMPReductionClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getColonLoc(),
+      C->getLocEnd(), ReductionIdScopeSpec, NameInfo);
+}
+
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
@@ -6501,17 +6682,36 @@
     ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
     if (EVar.isInvalid())
       return nullptr;
-    Vars.push_back(EVar.take());
+    Vars.push_back(EVar.get());
   }
   ExprResult Step = getDerived().TransformExpr(C->getStep());
   if (Step.isInvalid())
     return nullptr;
-  return getDerived().RebuildOMPLinearClause(
-      Vars, Step.take(), C->getLocStart(), C->getLParenLoc(), C->getColonLoc(),
-      C->getLocEnd());
+  return getDerived().RebuildOMPLinearClause(Vars, Step.get(), C->getLocStart(),
+                                             C->getLParenLoc(),
+                                             C->getColonLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
+  if (Alignment.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPAlignedClause(
+      Vars, Alignment.get(), C->getLocStart(), C->getLParenLoc(),
+      C->getColonLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
@@ -6520,12 +6720,25 @@
     ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
     if (EVar.isInvalid())
       return nullptr;
-    Vars.push_back(EVar.take());
+    Vars.push_back(EVar.get());
   }
-  return getDerived().RebuildOMPCopyinClause(Vars,
-                                             C->getLocStart(),
-                                             C->getLParenLoc(),
-                                             C->getLocEnd());
+  return getDerived().RebuildOMPCopyinClause(Vars, C->getLocStart(),
+                                             C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  return getDerived().RebuildOMPCopyprivateClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
 //===----------------------------------------------------------------------===//
@@ -6534,7 +6747,7 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -6571,7 +6784,7 @@
     // FIXME: this is a bit instantiation-specific.
     SemaRef.MarkDeclRefReferenced(E);
 
-    return SemaRef.Owned(E);
+    return E;
   }
 
   TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
@@ -6592,31 +6805,31 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -6651,13 +6864,13 @@
     ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i));
     if (AssocExpr.isInvalid())
       return ExprError();
-    AssocExprs.push_back(AssocExpr.release());
+    AssocExprs.push_back(AssocExpr.get());
   }
 
   return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
                                                   E->getDefaultLoc(),
                                                   E->getRParenLoc(),
-                                                  ControllingExpr.release(),
+                                                  ControllingExpr.get(),
                                                   AssocTypes,
                                                   AssocExprs);
 }
@@ -6670,7 +6883,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
                                        E->getRParen());
@@ -6683,7 +6896,7 @@
 ExprResult
 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
   if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
-    return getDerived().TransformDependentScopeDeclRefExpr(DRE, true);
+    return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr);
   else
     return getDerived().TransformExpr(E);
 }
@@ -6700,7 +6913,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
                                            E->getOpcode(),
@@ -6765,7 +6978,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeSourceInfo() &&
       !ExprChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   // Build a new offsetof expression.
   return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
@@ -6778,7 +6991,7 @@
 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
   assert(getDerived().AlreadyTransformed(E->getType()) &&
          "opaque value expression requires transformation");
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -6798,7 +7011,7 @@
   // expression must have been an lvalue-to-rvalue conversion which we
   // should reapply.
   if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
-    result = SemaRef.checkPseudoObjectRValue(result.take());
+    result = SemaRef.checkPseudoObjectRValue(result.get());
 
   return result;
 }
@@ -6815,7 +7028,7 @@
       return ExprError();
 
     if (!getDerived().AlwaysRebuild() && OldT == NewT)
-      return SemaRef.Owned(E);
+      return E;
 
     return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
                                                     E->getKind(),
@@ -6828,12 +7041,26 @@
   EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
                                                Sema::ReuseLambdaContextDecl);
 
-  ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
-  if (SubExpr.isInvalid())
+  // Try to recover if we have something like sizeof(T::X) where X is a type.
+  // Notably, there must be *exactly* one set of parens if X is a type.
+  TypeSourceInfo *RecoveryTSI = nullptr;
+  ExprResult SubExpr;
+  auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
+  if (auto *DRE =
+          PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
+    SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
+        PE, DRE, false, &RecoveryTSI);
+  else
+    SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
+
+  if (RecoveryTSI) {
+    return getDerived().RebuildUnaryExprOrTypeTrait(
+        RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
+  } else if (SubExpr.isInvalid())
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
                                                   E->getOperatorLoc(),
@@ -6856,7 +7083,7 @@
   if (!getDerived().AlwaysRebuild() &&
       LHS.get() == E->getLHS() &&
       RHS.get() == E->getRHS())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildArraySubscriptExpr(LHS.get(),
                                            /*FIXME:*/E->getLHS()->getLocStart(),
@@ -6936,7 +7163,7 @@
     // FIXME: this is a bit instantiation-specific.
     SemaRef.MarkMemberReferenced(E);
 
-    return SemaRef.Owned(E);
+    return E;
   }
 
   TemplateArgumentListInfo TransArgs;
@@ -6985,7 +7212,7 @@
   if (!getDerived().AlwaysRebuild() &&
       LHS.get() == E->getLHS() &&
       RHS.get() == E->getRHS())
-    return SemaRef.Owned(E);
+    return E;
 
   Sema::FPContractStateRAII FPContractState(getSema());
   getSema().FPFeatures.fp_contract = E->isFPContractable();
@@ -7018,9 +7245,9 @@
   if (!getDerived().AlwaysRebuild() &&
       commonExpr.get() == e->getCommon() &&
       rhs.get() == e->getFalseExpr())
-    return SemaRef.Owned(e);
+    return e;
 
-  return getDerived().RebuildConditionalOperator(commonExpr.take(),
+  return getDerived().RebuildConditionalOperator(commonExpr.get(),
                                                  e->getQuestionLoc(),
                                                  nullptr,
                                                  e->getColonLoc(),
@@ -7046,7 +7273,7 @@
       Cond.get() == E->getCond() &&
       LHS.get() == E->getLHS() &&
       RHS.get() == E->getRHS())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildConditionalOperator(Cond.get(),
                                                  E->getQuestionLoc(),
@@ -7078,7 +7305,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeInfoAsWritten() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
                                             Type,
@@ -7121,7 +7348,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
-    return SemaRef.Owned(E);
+    return E;
 
   // FIXME: Bad source location
   SourceLocation FakeOperatorLoc =
@@ -7142,7 +7369,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && !InitChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
                                       E->getRBraceLoc(), E->getType());
@@ -7180,7 +7407,7 @@
                                                D->getLBracketLoc()));
 
       ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
-      ArrayExprs.push_back(Index.release());
+      ArrayExprs.push_back(Index.get());
       continue;
     }
 
@@ -7202,14 +7429,14 @@
     ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
       End.get() != E->getArrayRangeEnd(*D);
 
-    ArrayExprs.push_back(Start.release());
-    ArrayExprs.push_back(End.release());
+    ArrayExprs.push_back(Start.get());
+    ArrayExprs.push_back(End.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
       Init.get() == E->getInit() &&
       !ExprChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
                                                 E->getEqualOrColonLoc(),
@@ -7230,7 +7457,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildImplicitValueInitExpr(T);
 }
@@ -7249,7 +7476,7 @@
   if (!getDerived().AlwaysRebuild() &&
       TInfo == E->getWrittenTypeInfo() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
                                        TInfo, E->getRParenLoc());
@@ -7328,7 +7555,7 @@
       Cond.get() == E->getCond() &&
       LHS.get() == E->getLHS() &&
       RHS.get() == E->getRHS())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
                                         Cond.get(), LHS.get(), RHS.get(),
@@ -7338,7 +7565,7 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -7480,7 +7707,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeInfoAsWritten() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
   return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
                                               E->getStmtClass(),
                                               E->getAngleBrackets().getBegin(),
@@ -7533,7 +7760,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeInfoAsWritten() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXFunctionalCastExpr(Type,
                                                    E->getLParenLoc(),
@@ -7552,7 +7779,7 @@
 
     if (!getDerived().AlwaysRebuild() &&
         TInfo == E->getTypeOperandSourceInfo())
-      return SemaRef.Owned(E);
+      return E;
 
     return getDerived().RebuildCXXTypeidExpr(E->getType(),
                                              E->getLocStart(),
@@ -7573,7 +7800,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getExprOperand())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXTypeidExpr(E->getType(),
                                            E->getLocStart(),
@@ -7592,7 +7819,7 @@
 
     if (!getDerived().AlwaysRebuild() &&
         TInfo == E->getTypeOperandSourceInfo())
-      return SemaRef.Owned(E);
+      return E;
 
     return getDerived().RebuildCXXUuidofExpr(E->getType(),
                                              E->getLocStart(),
@@ -7608,7 +7835,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getExprOperand())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXUuidofExpr(E->getType(),
                                            E->getLocStart(),
@@ -7619,14 +7846,14 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
                                                      CXXNullPtrLiteralExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -7637,7 +7864,7 @@
   if (!getDerived().AlwaysRebuild() && T == E->getType()) {
     // Make sure that we capture 'this'.
     getSema().CheckCXXThisCapture(E->getLocStart());
-    return SemaRef.Owned(E);
+    return E;
   }
 
   return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit());
@@ -7652,7 +7879,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
                                           E->isThrownVariableInScope());
@@ -7669,7 +7896,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       Param == E->getParam())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param);
 }
@@ -7684,7 +7911,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && Field == E->getField())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
 }
@@ -7699,7 +7926,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getTypeSourceInfo())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXScalarValueInitExpr(T,
                                           /*FIXME:*/T->getTypeLoc().getEndLoc(),
@@ -7780,7 +8007,7 @@
       }
     }
 
-    return SemaRef.Owned(E);
+    return E;
   }
 
   QualType AllocType = AllocTypeInfo->getType();
@@ -7795,16 +8022,14 @@
       // Do nothing
     } else if (const ConstantArrayType *ConsArrayT
                                      = dyn_cast<ConstantArrayType>(ArrayT)) {
-      ArraySize
-        = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
-                                               ConsArrayT->getSize(),
-                                               SemaRef.Context.getSizeType(),
-                                               /*FIXME:*/E->getLocStart()));
+      ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
+                                         SemaRef.Context.getSizeType(),
+                                         /*FIXME:*/ E->getLocStart());
       AllocType = ConsArrayT->getElementType();
     } else if (const DependentSizedArrayType *DepArrayT
                               = dyn_cast<DependentSizedArrayType>(ArrayT)) {
       if (DepArrayT->getSizeExpr()) {
-        ArraySize = SemaRef.Owned(DepArrayT->getSizeExpr());
+        ArraySize = DepArrayT->getSizeExpr();
         AllocType = DepArrayT->getElementType();
       }
     }
@@ -7820,7 +8045,7 @@
                                         AllocTypeInfo,
                                         ArraySize.get(),
                                         E->getDirectInitRange(),
-                                        NewInit.take());
+                                        NewInit.get());
 }
 
 template<typename Derived>
@@ -7858,7 +8083,7 @@
       }
     }
 
-    return SemaRef.Owned(E);
+    return E;
   }
 
   return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
@@ -8156,7 +8381,7 @@
   }
 
   if (!getDerived().AlwaysRebuild() && !ArgChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildTypeTrait(E->getTrait(),
                                        E->getLocStart(),
@@ -8173,7 +8398,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getQueriedTypeSourceInfo())
-    return SemaRef.Owned(E);
+    return E;
 
   ExprResult SubExpr;
   {
@@ -8183,7 +8408,7 @@
       return ExprError();
 
     if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
-      return SemaRef.Owned(E);
+      return E;
   }
 
   return getDerived().RebuildArrayTypeTrait(E->getTrait(),
@@ -8204,25 +8429,44 @@
       return ExprError();
 
     if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
-      return SemaRef.Owned(E);
+      return E;
   }
 
   return getDerived().RebuildExpressionTrait(
       E->getTrait(), E->getLocStart(), SubExpr.get(), E->getLocEnd());
 }
 
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
-                                               DependentScopeDeclRefExpr *E) {
-  return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand*/false);
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
+    ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
+    TypeSourceInfo **RecoveryTSI) {
+  ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
+      DRE, AddrTaken, RecoveryTSI);
+
+  // Propagate both errors and recovered types, which return ExprEmpty.
+  if (!NewDRE.isUsable())
+    return NewDRE;
+
+  // We got an expr, wrap it up in parens.
+  if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
+    return PE;
+  return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
+                                       PE->getRParen());
+}
+
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
+    DependentScopeDeclRefExpr *E) {
+  return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
+                                            nullptr);
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
                                                DependentScopeDeclRefExpr *E,
-                                               bool IsAddressOfOperand) {
+                                               bool IsAddressOfOperand,
+                                               TypeSourceInfo **RecoveryTSI) {
   assert(E->getQualifierLoc());
   NestedNameSpecifierLoc QualifierLoc
   = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
@@ -8245,13 +8489,11 @@
         // Note: it is sufficient to compare the Name component of NameInfo:
         // if name has not changed, DNLoc has not changed either.
         NameInfo.getName() == E->getDeclName())
-      return SemaRef.Owned(E);
+      return E;
 
-    return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc,
-                                                        TemplateKWLoc,
-                                                        NameInfo,
-                                                        /*TemplateArgs*/nullptr,
-                                                        IsAddressOfOperand);
+    return getDerived().RebuildDependentScopeDeclRefExpr(
+        QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
+        IsAddressOfOperand, RecoveryTSI);
   }
 
   TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
@@ -8260,11 +8502,9 @@
                                               TransArgs))
     return ExprError();
 
-  return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc,
-                                                       TemplateKWLoc,
-                                                       NameInfo,
-                                                       &TransArgs,
-                                                       IsAddressOfOperand);
+  return getDerived().RebuildDependentScopeDeclRefExpr(
+      QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
+      RecoveryTSI);
 }
 
 template<typename Derived>
@@ -8305,7 +8545,7 @@
     // Mark the constructor as referenced.
     // FIXME: Instantiation-specific
     SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
-    return SemaRef.Owned(E);
+    return E;
   }
 
   return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
@@ -8614,6 +8854,9 @@
           // Capture the transformed variable.
           getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
         }
+
+        // FIXME: Retain a pack expansion if RetainExpansion is true.
+
         continue;
       }
 
@@ -8654,7 +8897,7 @@
     return ExprError();
   }
 
-  return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(),
+  return getSema().ActOnLambdaExpr(E->getLocStart(), Body.get(),
                                    /*CurScope=*/nullptr,
                                    /*IsInstantiation=*/true);
 }
@@ -8677,7 +8920,7 @@
   if (!getDerived().AlwaysRebuild() &&
       T == E->getTypeSourceInfo() &&
       !ArgumentChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   // FIXME: we're faking the locations of the commas
   return getDerived().RebuildCXXUnresolvedConstructExpr(T,
@@ -8757,7 +9000,7 @@
         QualifierLoc == E->getQualifierLoc() &&
         NameInfo.getName() == E->getMember() &&
         FirstQualifierInScope == E->getFirstQualifierFoundInScope())
-      return SemaRef.Owned(E);
+      return E;
 
     return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
                                                        BaseType,
@@ -8797,7 +9040,7 @@
     Base = getDerived().TransformExpr(Old->getBase());
     if (Base.isInvalid())
       return ExprError();
-    Base = getSema().PerformMemberExprBaseConversion(Base.take(),
+    Base = getSema().PerformMemberExprBaseConversion(Base.get(),
                                                      Old->isArrow());
     if (Base.isInvalid())
       return ExprError();
@@ -8898,7 +9141,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
 }
@@ -8911,7 +9154,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
                                            E->getNumExpansions());
@@ -8923,7 +9166,7 @@
   // If E is not value-dependent, then nothing will change when we transform it.
   // Note: This is an instantiation-centric view.
   if (!E->isValueDependent())
-    return SemaRef.Owned(E);
+    return E;
 
   // Note: None of the implementations of TryExpandParameterPacks can ever
   // produce a diagnostic when given only a single unexpanded parameter pack,
@@ -8939,7 +9182,7 @@
     return ExprError();
 
   if (RetainExpansion)
-    return SemaRef.Owned(E);
+    return E;
 
   NamedDecl *Pack = E->getPack();
   if (!ShouldExpand) {
@@ -8962,7 +9205,7 @@
 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
                                           SubstNonTypeTemplateParmPackExpr *E) {
   // Default behavior is to do nothing with this transformation.
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -8970,14 +9213,14 @@
 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
                                           SubstNonTypeTemplateParmExpr *E) {
   // Default behavior is to do nothing with this transformation.
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
   // Default behavior is to do nothing with this transformation.
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -9003,7 +9246,7 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -9015,7 +9258,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
 }
@@ -9118,6 +9361,7 @@
 
         // If any unexpanded parameter packs remain, we still have a
         // pack expansion.
+        // FIXME: Can this really happen?
         if (Key.get()->containsUnexpandedParameterPack() ||
             Value.get()->containsUnexpandedParameterPack())
           Element.EllipsisLoc = OrigElement.EllipsisLoc;
@@ -9125,6 +9369,8 @@
         Elements.push_back(Element);
       }
 
+      // FIXME: Retain a pack expansion if RetainExpansion is true.
+
       // We've finished with this pack expansion.
       continue;
     }
@@ -9170,7 +9416,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       EncodedTypeInfo == E->getEncodedTypeSourceInfo())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
                                             EncodedTypeInfo,
@@ -9202,7 +9448,7 @@
   if (!getDerived().AlwaysRebuild() &&
       TSInfo == E->getTypeInfoAsWritten() &&
       Result.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
                                       E->getBridgeKeywordLoc(), TSInfo,
@@ -9272,13 +9518,13 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -9294,7 +9540,7 @@
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
                                              E->getLocation(),
@@ -9307,7 +9553,7 @@
   // 'super' and types never change. Property never changes. Just
   // retain the existing expression.
   if (!E->isObjectReceiver())
-    return SemaRef.Owned(E);
+    return E;
 
   // Transform the base expression.
   ExprResult Base = getDerived().TransformExpr(E->getBase());
@@ -9319,7 +9565,7 @@
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
-    return SemaRef.Owned(E);
+    return E;
 
   if (E->isExplicitProperty())
     return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
@@ -9349,7 +9595,7 @@
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
                                                   Base.get(), Key.get(),
@@ -9368,7 +9614,7 @@
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
                                          E->getOpLoc(),
@@ -9387,7 +9633,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       !ArgumentChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
                                                SubExprs,
@@ -9408,7 +9654,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeSourceInfo() &&
       SrcExpr.get() == E->getSrcExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
                                                SrcExpr.get(), Type,
@@ -9508,7 +9754,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       !ArgumentChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
                                         RetTy, E->getOp(), E->getRParenLoc());
@@ -9662,7 +9908,7 @@
 template<typename Derived>
 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
     QualType T,
-    llvm::MutableArrayRef<QualType> ParamTypes,
+    MutableArrayRef<QualType> ParamTypes,
     const FunctionProtoType::ExtProtoInfo &EPI) {
   return SemaRef.BuildFunctionType(T, ParamTypes,
                                    getDerived().getBaseLocation(),
@@ -9796,6 +10042,24 @@
   Expr *Callee = OrigCallee->IgnoreParenCasts();
   bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
 
+  if (First->getObjectKind() == OK_ObjCProperty) {
+    BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+    if (BinaryOperator::isAssignmentOp(Opc))
+      return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
+                                                 First, Second);
+    ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
+    if (Result.isInvalid())
+      return ExprError();
+    First = Result.get();
+  }
+
+  if (Second && Second->getObjectKind() == OK_ObjCProperty) {
+    ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
+    if (Result.isInvalid())
+      return ExprError();
+    Second = Result.get();
+  }
+
   // Determine whether this should be a builtin operation.
   if (Op == OO_Subscript) {
     if (!First->getType()->isOverloadableType() &&
@@ -9951,14 +10215,18 @@
   }
   getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
                                      S->getCapturedRegionKind(), Params);
-  StmtResult Body = getDerived().TransformStmt(S->getCapturedStmt());
+  StmtResult Body;
+  {
+    Sema::CompoundScopeRAII CompoundScope(getSema());
+    Body = getDerived().TransformStmt(S->getCapturedStmt());
+  }
 
   if (Body.isInvalid()) {
     getSema().ActOnCapturedRegionError();
     return StmtError();
   }
 
-  return getSema().ActOnCapturedRegionEnd(Body.take());
+  return getSema().ActOnCapturedRegionEnd(Body.get());
 }
 
 } // end namespace clang
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 4ea95d0..f18122d 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -52,10 +52,10 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SaveAndRestore.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include <algorithm>
 #include <cstdio>
 #include <iterator>
+#include <system_error>
 
 using namespace clang;
 using namespace clang::serialization;
@@ -328,13 +328,11 @@
   return false;
 }
 
-static DiagnosticsEngine::ExtensionHandling
-isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
-  DiagnosticsEngine::ExtensionHandling Ext =
-      Diags.getExtensionHandlingBehavior();
-  if (Ext == DiagnosticsEngine::Ext_Warn && Diags.getWarningsAsErrors())
-    Ext = DiagnosticsEngine::Ext_Error;
-  return Ext;
+static bool isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
+  diag::Severity Ext = Diags.getExtensionHandlingBehavior();
+  if (Ext == diag::Severity::Warning && Diags.getWarningsAsErrors())
+    return true;
+  return Ext >= diag::Severity::Error;
 }
 
 static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags,
@@ -380,7 +378,7 @@
   DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs());
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-      new DiagnosticsEngine(DiagIDs, DiagOpts.getPtr()));
+      new DiagnosticsEngine(DiagIDs, DiagOpts.get()));
   // This should never fail, because we would have processed these options
   // before writing them to an ASTFile.
   ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);
@@ -807,7 +805,7 @@
         I -= *SI;
 
         uint32_t LocalMacroID = *I;
-        llvm::ArrayRef<uint32_t> Overrides;
+        ArrayRef<uint32_t> Overrides;
         if (*SI != 1)
           Overrides = llvm::makeArrayRef(&I[2], *SI - 2);
         Reader.addPendingMacroFromModule(II, &F, LocalMacroID, Overrides);
@@ -1559,7 +1557,7 @@
 void
 ASTReader::addPendingMacroFromModule(IdentifierInfo *II, ModuleFile *M,
                                      GlobalMacroID GMacID,
-                                     llvm::ArrayRef<SubmoduleID> Overrides) {
+                                     ArrayRef<SubmoduleID> Overrides) {
   assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
   SubmoduleID *OverrideData = nullptr;
   if (!Overrides.empty()) {
@@ -1728,9 +1726,9 @@
 
   SubmoduleID getSubmoduleID() const { return SubModID; }
 
-  llvm::ArrayRef<SubmoduleID> getOverriddenSubmodules() const {
+  ArrayRef<SubmoduleID> getOverriddenSubmodules() const {
     if (!Overrides)
-      return llvm::ArrayRef<SubmoduleID>();
+      return None;
     return llvm::makeArrayRef(Overrides + 1, *Overrides);
   }
 
@@ -1880,7 +1878,7 @@
 
 void ASTReader::removeOverriddenMacros(IdentifierInfo *II,
                                        AmbiguousMacros &Ambig,
-                                       llvm::ArrayRef<SubmoduleID> Overrides) {
+                                       ArrayRef<SubmoduleID> Overrides) {
   for (unsigned OI = 0, ON = Overrides.size(); OI != ON; ++OI) {
     SubmoduleID OwnerID = Overrides[OI];
 
@@ -1905,7 +1903,7 @@
 
 ASTReader::AmbiguousMacros *
 ASTReader::removeOverriddenMacros(IdentifierInfo *II,
-                                  llvm::ArrayRef<SubmoduleID> Overrides) {
+                                  ArrayRef<SubmoduleID> Overrides) {
   MacroDirective *Prev = PP.getMacroDirective(II);
   if (!Prev && Overrides.empty())
     return nullptr;
@@ -3464,8 +3462,13 @@
   case OutOfDate:
   case VersionMismatch:
   case ConfigurationMismatch:
-  case HadErrors:
+  case HadErrors: {
+    llvm::SmallPtrSet<ModuleFile *, 4> LoadedSet;
+    for (const ImportedModule &IM : Loaded)
+      LoadedSet.insert(IM.Mod);
+
     ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end(),
+                            LoadedSet,
                             Context.getLangOpts().Modules
                               ? &PP.getHeaderSearchInfo().getModuleMap()
                               : nullptr);
@@ -3475,7 +3478,7 @@
     GlobalIndex.reset();
     ModuleMgr.setGlobalIndex(nullptr);
     return ReadResult;
-
+  }
   case Success:
     break;
   }
@@ -5022,9 +5025,9 @@
         if (DiagID == (unsigned)-1) {
           break; // no more diag/map pairs for this location.
         }
-        diag::Mapping Map = (diag::Mapping)F.PragmaDiagMappings[Idx++];
-        DiagnosticMappingInfo MappingInfo = Diag.makeMappingInfo(Map, Loc);
-        Diag.GetCurDiagState()->setMappingInfo(DiagID, MappingInfo);
+        diag::Severity Map = (diag::Severity)F.PragmaDiagMappings[Idx++];
+        DiagnosticMapping Mapping = Diag.makeUserMapping(Map, Loc);
+        Diag.GetCurDiagState()->setMapping(DiagID, Mapping);
       }
     }
   }
@@ -8088,7 +8091,10 @@
     }
 
     // Perform any pending declaration updates.
-    while (!PendingUpdateRecords.empty()) {
+    //
+    // Don't do this if we have known-incomplete redecl chains: it relies on
+    // being able to walk redeclaration chains.
+    while (PendingDeclChains.empty() && !PendingUpdateRecords.empty()) {
       auto Update = PendingUpdateRecords.pop_back_val();
       ReadingKindTracker ReadingKind(Read_Decl, *this);
       loadDeclUpdateRecords(Update.first, Update.second);
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 8a0849c..d8495da 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -664,8 +664,7 @@
       // We avoid getASTContext because a decl in the parent hierarchy may
       // be initializing.
       llvm::FoldingSetNodeID ID;
-      FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(),
-                                                  TemplArgs.size(), C);
+      FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs, C);
       void *InsertPos = nullptr;
       FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr();
       CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos);
@@ -1480,6 +1479,9 @@
   if (WasDefinition) {
     DeclID KeyFn = ReadDeclID(Record, Idx);
     if (KeyFn && D->IsCompleteDefinition)
+      // FIXME: This is wrong for the ARM ABI, where some other module may have
+      // made this function no longer be a key function. We need an update
+      // record or similar for that case.
       C.KeyFunctions[D] = KeyFn;
   }
 
@@ -2491,6 +2493,37 @@
   D->IdentifierNamespace |=
       Previous->IdentifierNamespace &
       (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
+
+  // If the previous declaration is marked as used, then this declaration should
+  // be too.
+  if (Previous->Used)
+    D->Used = true;
+
+  // If the previous declaration is an inline function declaration, then this
+  // declaration is too.
+  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+    if (cast<FunctionDecl>(Previous)->IsInline != FD->IsInline) {
+      // FIXME: [dcl.fct.spec]p4:
+      //   If a function with external linkage is declared inline in one
+      //   translation unit, it shall be declared inline in all translation
+      //   units in which it appears.
+      //
+      // Be careful of this case:
+      //
+      // module A:
+      //   template<typename T> struct X { void f(); };
+      //   template<typename T> inline void X<T>::f() {}
+      //
+      // module B instantiates the declaration of X<int>::f
+      // module C instantiates the definition of X<int>::f
+      //
+      // If module B and C are merged, we do not have a violation of this rule.
+      //
+      //if (!FD->IsInline || Previous->getOwningModule())
+      //  Diag(FD->getLocation(), diag::err_odr_differing_inline);
+      FD->IsInline = true;
+    }
+  }
 }
 
 template<typename DeclT>
@@ -3162,8 +3195,17 @@
         return;
       }
 
-      if (Record[Idx++])
-        FD->setImplicitlyInline();
+      if (Record[Idx++]) {
+        // Maintain AST consistency: any later redeclarations of this function
+        // are inline if this one is. (We might have merged another declaration
+        // into this one.)
+        for (auto *D = FD->getMostRecentDecl(); /**/;
+             D = D->getPreviousDecl()) {
+          D->setImplicitlyInline();
+          if (D == FD)
+            break;
+        }
+      }
       FD->setInnerLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
       if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
         std::tie(CD->CtorInitializers, CD->NumCtorInitializers) =
@@ -3245,7 +3287,14 @@
     case UPD_DECL_MARKED_USED: {
       // FIXME: This doesn't send the right notifications if there are
       // ASTMutationListeners other than an ASTWriter.
-      D->Used = true;
+
+      // Maintain AST consistency: any later redeclarations are used too.
+      for (auto *Redecl = D->getMostRecentDecl(); /**/;
+           Redecl = Redecl->getPreviousDecl()) {
+        Redecl->Used = true;
+        if (Redecl == D)
+          break;
+      }
       break;
     }
 
diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h
index 9f2065e..a63e362 100644
--- a/lib/Serialization/ASTReaderInternals.h
+++ b/lib/Serialization/ASTReaderInternals.h
@@ -17,7 +17,6 @@
 #include "clang/Serialization/ASTBitCodes.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/OnDiskHashTable.h"
-#include <sys/stat.h>
 #include <utility>
 
 namespace clang {
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 89bc7fe..cee2aa2 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1609,6 +1609,11 @@
   E->setExprOperand(Reader.ReadSubExpr());
 }
 
+void ASTStmtReader::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
+  VisitStmt(S);
+  S->setLeaveLoc(ReadSourceLocation(Record, Idx));
+}
+
 void ASTStmtReader::VisitSEHExceptStmt(SEHExceptStmt *S) {
   VisitStmt(S);
   S->Loc = ReadSourceLocation(Record, Idx);
@@ -1691,21 +1696,42 @@
   case OMPC_proc_bind:
     C = new (Context) OMPProcBindClause();
     break;
+  case OMPC_schedule:
+    C = new (Context) OMPScheduleClause();
+    break;
+  case OMPC_ordered:
+    C = new (Context) OMPOrderedClause();
+    break;
+  case OMPC_nowait:
+    C = new (Context) OMPNowaitClause();
+    break;
   case OMPC_private:
     C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);
     break;
   case OMPC_firstprivate:
     C = OMPFirstprivateClause::CreateEmpty(Context, Record[Idx++]);
     break;
+  case OMPC_lastprivate:
+    C = OMPLastprivateClause::CreateEmpty(Context, Record[Idx++]);
+    break;
   case OMPC_shared:
     C = OMPSharedClause::CreateEmpty(Context, Record[Idx++]);
     break;
+  case OMPC_reduction:
+    C = OMPReductionClause::CreateEmpty(Context, Record[Idx++]);
+    break;
   case OMPC_linear:
     C = OMPLinearClause::CreateEmpty(Context, Record[Idx++]);
     break;
+  case OMPC_aligned:
+    C = OMPAlignedClause::CreateEmpty(Context, Record[Idx++]);
+    break;
   case OMPC_copyin:
     C = OMPCopyinClause::CreateEmpty(Context, Record[Idx++]);
     break;
+  case OMPC_copyprivate:
+    C = OMPCopyprivateClause::CreateEmpty(Context, Record[Idx++]);
+    break;
   }
   Visit(C);
   C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
@@ -1748,6 +1774,19 @@
   C->setProcBindKindKwLoc(Reader->ReadSourceLocation(Record, Idx));
 }
 
+void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  C->setScheduleKind(
+       static_cast<OpenMPScheduleClauseKind>(Record[Idx++]));
+  C->setChunkSize(Reader->Reader.ReadSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setScheduleKindLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setCommaLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
+void OMPClauseReader::VisitOMPOrderedClause(OMPOrderedClause *) {}
+
+void OMPClauseReader::VisitOMPNowaitClause(OMPNowaitClause *) {}
+
 void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
   unsigned NumVars = C->varlist_size();
@@ -1768,6 +1807,16 @@
   C->setVarRefs(Vars);
 }
 
+void OMPClauseReader::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
 void OMPClauseReader::VisitOMPSharedClause(OMPSharedClause *C) {
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
   unsigned NumVars = C->varlist_size();
@@ -1778,6 +1827,24 @@
   C->setVarRefs(Vars);
 }
 
+void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+  NestedNameSpecifierLoc NNSL =
+    Reader->Reader.ReadNestedNameSpecifierLoc(Reader->F, Record, Idx);
+  DeclarationNameInfo DNI;
+  Reader->ReadDeclarationNameInfo(DNI, Record, Idx);
+  C->setQualifierLoc(NNSL);
+  C->setNameInfo(DNI);
+
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
 void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) {
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
   C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
@@ -1790,6 +1857,18 @@
   C->setStep(Reader->Reader.ReadSubExpr());
 }
 
+void OMPClauseReader::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+  C->setAlignment(Reader->Reader.ReadSubExpr());
+}
+
 void OMPClauseReader::VisitOMPCopyinClause(OMPCopyinClause *C) {
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
   unsigned NumVars = C->varlist_size();
@@ -1800,6 +1879,16 @@
   C->setVarRefs(Vars);
 }
 
+void OMPClauseReader::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
 //===----------------------------------------------------------------------===//
 // OpenMP Directives.
 //===----------------------------------------------------------------------===//
@@ -1828,6 +1917,47 @@
   VisitOMPExecutableDirective(D);
 }
 
+void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) {
+  VisitStmt(D);
+  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
+  Idx += 2;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPSectionDirective(OMPSectionDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
+  VisitStmt(D);
+  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
+  Idx += 2;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPParallelSectionsDirective(
+    OMPParallelSectionsDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
 //===----------------------------------------------------------------------===//
 // ASTReader Implementation
 //===----------------------------------------------------------------------===//
@@ -2271,6 +2401,9 @@
     case EXPR_OBJC_BOOL_LITERAL:
       S = new (Context) ObjCBoolLiteralExpr(Empty);
       break;
+    case STMT_SEH_LEAVE:
+      S = new (Context) SEHLeaveStmt(Empty);
+      break;
     case STMT_SEH_EXCEPT:
       S = new (Context) SEHExceptStmt(Empty);
       break;
@@ -2315,6 +2448,41 @@
       break;
     }
 
+    case STMT_OMP_FOR_DIRECTIVE: {
+      unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+      unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPForDirective::CreateEmpty(Context, NumClauses, CollapsedNum,
+                                       Empty);
+      break;
+    }
+
+    case STMT_OMP_SECTIONS_DIRECTIVE:
+      S = OMPSectionsDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
+    case STMT_OMP_SECTION_DIRECTIVE:
+      S = OMPSectionDirective::CreateEmpty(Context, Empty);
+      break;
+
+    case STMT_OMP_SINGLE_DIRECTIVE:
+      S = OMPSingleDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
+    case STMT_OMP_PARALLEL_FOR_DIRECTIVE: {
+      unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+      unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPParallelForDirective::CreateEmpty(Context, NumClauses,
+                                               CollapsedNum, Empty);
+      break;
+    }
+
+    case STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE:
+      S = OMPParallelSectionsDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
     case EXPR_CXX_OPERATOR_CALL:
       S = new (Context) CXXOperatorCallExpr(Context, Empty);
       break;
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 35da82c..a02a959 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2542,7 +2542,7 @@
              I = point.State->begin(), E = point.State->end(); I != E; ++I) {
         if (I->second.isPragma()) {
           Record.push_back(I->first);
-          Record.push_back(I->second.getMapping());
+          Record.push_back((unsigned)I->second.getSeverity());
         }
       }
       Record.push_back(-1); // mark the end of the diag/map pairs for this
@@ -3163,7 +3163,7 @@
   }
 
   static void emitMacroOverrides(raw_ostream &Out,
-                                 llvm::ArrayRef<SubmoduleID> Overridden) {
+                                 ArrayRef<SubmoduleID> Overridden) {
     if (!Overridden.empty()) {
       using namespace llvm::support;
       endian::Writer<little> LE(Out);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 347473c..47ce747 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -1515,8 +1515,6 @@
   // ObjC Ivar
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
-  // getBackingIvarReferencedInAccessor
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   // Type Source Info
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index a79772a..8f0c69e 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1650,6 +1650,12 @@
   Code = serialization::STMT_SEH_TRY;
 }
 
+void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getLeaveLoc(), Record);
+  Code = serialization::STMT_SEH_LEAVE;
+}
+
 //===----------------------------------------------------------------------===//
 // OpenMP Clauses.
 //===----------------------------------------------------------------------===//
@@ -1707,6 +1713,18 @@
   Writer->Writer.AddSourceLocation(C->getProcBindKindKwLoc(), Record);
 }
 
+void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  Record.push_back(C->getScheduleKind());
+  Writer->Writer.AddStmt(C->getChunkSize());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getScheduleKindLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getCommaLoc(), Record);
+}
+
+void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *) {}
+
+void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *) {}
+
 void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
@@ -1721,6 +1739,13 @@
     Writer->Writer.AddStmt(VE);
 }
 
+void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
 void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
@@ -1728,6 +1753,16 @@
     Writer->Writer.AddStmt(VE);
 }
 
+void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
+  Writer->Writer.AddNestedNameSpecifierLoc(C->getQualifierLoc(), Record);
+  Writer->Writer.AddDeclarationNameInfo(C->getNameInfo(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
 void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
@@ -1737,6 +1772,15 @@
   Writer->Writer.AddStmt(C->getStep());
 }
 
+void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+  Writer->Writer.AddStmt(C->getAlignment());
+}
+
 void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
@@ -1744,6 +1788,13 @@
     Writer->Writer.AddStmt(VE);
 }
 
+void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
 //===----------------------------------------------------------------------===//
 // OpenMP Directives.
 //===----------------------------------------------------------------------===//
@@ -1772,6 +1823,50 @@
   Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
 }
 
+void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  Record.push_back(D->getCollapsedNumber());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_FOR_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  Record.push_back(D->getCollapsedNumber());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPParallelSectionsDirective(
+    OMPParallelSectionsDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
+}
+
 //===----------------------------------------------------------------------===//
 // ASTWriter Implementation
 //===----------------------------------------------------------------------===//
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index 69c331b..9858122 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -239,10 +239,11 @@
   IndexPath += Path;
   llvm::sys::path::append(IndexPath, IndexFileName);
 
-  std::unique_ptr<llvm::MemoryBuffer> Buffer;
-  if (llvm::MemoryBuffer::getFile(IndexPath.c_str(), Buffer) !=
-      llvm::errc::success)
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferOrErr =
+      llvm::MemoryBuffer::getFile(IndexPath.c_str());
+  if (!BufferOrErr)
     return std::make_pair(nullptr, EC_NotFound);
+  std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(BufferOrErr.get());
 
   /// \brief The bitstream reader from which we'll read the AST file.
   llvm::BitstreamReader Reader((const unsigned char *)Buffer->getBufferStart(),
@@ -788,7 +789,7 @@
   GlobalModuleIndexBuilder Builder(FileMgr);
   
   // Load each of the module files.
-  llvm::error_code EC;
+  std::error_code EC;
   for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd;
        D != DEnd && !EC;
        D.increment(EC)) {
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 5613d37..2c10c11 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -18,7 +18,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 
 #ifndef NDEBUG
 #include "llvm/Support/GraphWriter.h"
@@ -104,13 +104,24 @@
       New->Buffer.reset(Buffer);
     } else {
       // Open the AST file.
-      llvm::error_code ec;
+      std::error_code ec;
       if (FileName == "-") {
-        ec = llvm::MemoryBuffer::getSTDIN(New->Buffer);
+        llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf =
+            llvm::MemoryBuffer::getSTDIN();
+        ec = Buf.getError();
         if (ec)
           ErrorStr = ec.message();
-      } else
-        New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr));
+        else
+          New->Buffer = std::move(Buf.get());
+      } else {
+        // Leave the FileEntry open so if it gets read again by another
+        // ModuleManager it must be the same underlying file.
+        // FIXME: Because FileManager::getFile() doesn't guarantee that it will
+        // give us an open file, this may not be 100% reliable.
+        New->Buffer.reset(FileMgr.getBufferForFile(New->File, &ErrorStr,
+                                                   /*IsVolatile*/false,
+                                                   /*ShouldClose*/false));
+      }
       
       if (!New->Buffer)
         return Missing;
@@ -135,16 +146,13 @@
   return NewModule? NewlyLoaded : AlreadyLoaded;
 }
 
-void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last,
-                                  ModuleMap *modMap) {
+void ModuleManager::removeModules(
+    ModuleIterator first, ModuleIterator last,
+    llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
+    ModuleMap *modMap) {
   if (first == last)
     return;
 
-  // The first file entry is about to be rebuilt (or there was an error), so
-  // there should be no references to it. Remove it from the cache to close it,
-  // as Windows doesn't seem to allow renaming over an open file.
-  FileMgr.invalidateCache((*first)->File);
-
   // Collect the set of module file pointers that we'll be removing.
   llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);
 
@@ -165,6 +173,13 @@
         mod->setASTFile(nullptr);
       }
     }
+
+    // Files that didn't make it through ReadASTCore successfully will be
+    // rebuilt (or there was an error). Invalidate them so that we can load the
+    // new files that will be renamed over the old ones.
+    if (LoadedSuccessfully.count(*victim) == 0)
+      FileMgr.invalidateCache((*victim)->File);
+
     delete *victim;
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/Android.mk b/lib/StaticAnalyzer/Checkers/Android.mk
index bb2a539..ab3da80 100644
--- a/lib/StaticAnalyzer/Checkers/Android.mk
+++ b/lib/StaticAnalyzer/Checkers/Android.mk
@@ -70,6 +70,7 @@
   StackAddrEscapeChecker.cpp \
   StreamChecker.cpp \
   TaintTesterChecker.cpp \
+  TestAfterDivZeroChecker.cpp \
   TraversalChecker.cpp \
   UndefBranchChecker.cpp \
   UndefCapturedBlockVarChecker.cpp \
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index d36679d..3fd5576 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -523,16 +523,17 @@
 }
 
 //===----------------------------------------------------------------------===//
-// CFRetain/CFRelease/CFMakeCollectable checking for null arguments.
+// CFRetain/CFRelease/CFMakeCollectable/CFAutorelease checking for null arguments.
 //===----------------------------------------------------------------------===//
 
 namespace {
 class CFRetainReleaseChecker : public Checker< check::PreStmt<CallExpr> > {
   mutable std::unique_ptr<APIMisuse> BT;
-  mutable IdentifierInfo *Retain, *Release, *MakeCollectable;
+  mutable IdentifierInfo *Retain, *Release, *MakeCollectable, *Autorelease;
 public:
   CFRetainReleaseChecker()
-      : Retain(nullptr), Release(nullptr), MakeCollectable(nullptr) {}
+      : Retain(nullptr), Release(nullptr), MakeCollectable(nullptr),
+        Autorelease(nullptr) {}
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
 };
 } // end anonymous namespace
@@ -554,13 +555,15 @@
     Retain = &Ctx.Idents.get("CFRetain");
     Release = &Ctx.Idents.get("CFRelease");
     MakeCollectable = &Ctx.Idents.get("CFMakeCollectable");
+    Autorelease = &Ctx.Idents.get("CFAutorelease");
     BT.reset(new APIMisuse(
-        this, "null passed to CFRetain/CFRelease/CFMakeCollectable"));
+        this, "null passed to CF memory management function"));
   }
 
-  // Check if we called CFRetain/CFRelease/CFMakeCollectable.
+  // Check if we called CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
   const IdentifierInfo *FuncII = FD->getIdentifier();
-  if (!(FuncII == Retain || FuncII == Release || FuncII == MakeCollectable))
+  if (!(FuncII == Retain || FuncII == Release || FuncII == MakeCollectable ||
+        FuncII == Autorelease))
     return;
 
   // FIXME: The rest of this just checks that the argument is non-null.
@@ -597,6 +600,8 @@
       description = "Null pointer argument in call to CFRelease";
     else if (FuncII == MakeCollectable)
       description = "Null pointer argument in call to CFMakeCollectable";
+    else if (FuncII == Autorelease)
+      description = "Null pointer argument in call to CFAutorelease";
     else
       llvm_unreachable("impossible case");
 
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 8e7a839..9fb22ec 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -64,6 +64,7 @@
   StackAddrEscapeChecker.cpp
   StreamChecker.cpp
   TaintTesterChecker.cpp
+  TestAfterDivZeroChecker.cpp
   TraversalChecker.cpp
   UndefBranchChecker.cpp
   UndefCapturedBlockVarChecker.cpp
diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td
index a457b44..44eb641 100644
--- a/lib/StaticAnalyzer/Checkers/Checkers.td
+++ b/lib/StaticAnalyzer/Checkers/Checkers.td
@@ -124,6 +124,10 @@
   HelpText<"Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables)">,
   DescFile<"CallAndMessageChecker.cpp">;
 
+def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">,
+  HelpText<"Check for division by variable that is later compared against 0. Either the comparison is useless or there is division by zero.">,
+  DescFile<"TestAfterDivZeroChecker.cpp">;
+
 } // end "alpha.core"
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
index efdc213..4ee0223 100644
--- a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -126,7 +126,7 @@
     os << "Array access";
     const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(S);
     AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
-                   State.getPtr(), N->getLocationContext());
+                   State.get(), N->getLocationContext());
     os << " results in a null pointer dereference";
     break;
   }
@@ -134,7 +134,7 @@
     os << "Dereference of null pointer";
     const UnaryOperator *U = cast<UnaryOperator>(S);
     AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(),
-                   State.getPtr(), N->getLocationContext(), true);
+                   State.get(), N->getLocationContext(), true);
     break;
   }
   case Stmt::MemberExprClass: {
@@ -143,7 +143,7 @@
       os << "Access to field '" << M->getMemberNameInfo()
          << "' results in a dereference of a null pointer";
       AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(),
-                     State.getPtr(), N->getLocationContext(), true);
+                     State.get(), N->getLocationContext(), true);
     }
     break;
   }
@@ -152,7 +152,7 @@
     os << "Access to instance variable '" << *IV->getDecl()
        << "' results in a dereference of a null pointer";
     AddDerefSource(os, Ranges, IV->getBase()->IgnoreParenCasts(),
-                   State.getPtr(), N->getLocationContext(), true);
+                   State.get(), N->getLocationContext(), true);
     break;
   }
   default:
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 0c130fe..eb699d6 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2340,14 +2340,27 @@
 
   // Get the SourceLocation for the allocation site.
   // FIXME: This will crash the analyzer if an allocation comes from an
-  // implicit call. (Currently there are no such allocations in Cocoa, though.)
-  const Stmt *AllocStmt;
+  // implicit call (ex: a destructor call).
+  // (Currently there are no such allocations in Cocoa, though.)
+  const Stmt *AllocStmt = 0;
   ProgramPoint P = AllocNode->getLocation();
   if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
     AllocStmt = Exit->getCalleeContext()->getCallSite();
-  else
-    AllocStmt = P.castAs<PostStmt>().getStmt();
-  assert(AllocStmt && "All allocations must come from explicit calls");
+  else {
+    // We are going to get a BlockEdge when the leak and allocation happen in
+    // different, non-nested frames (contexts). For example, the case where an
+    // allocation happens in a block that captures a reference to it and
+    // that reference is overwritten/dropped by another call to the block.
+    if (Optional<BlockEdge> Edge = P.getAs<BlockEdge>()) {
+      if (Optional<CFGStmt> St = Edge->getDst()->front().getAs<CFGStmt>()) {
+        AllocStmt = St->getStmt();
+      }
+    }
+    else {
+      AllocStmt = P.castAs<PostStmt>().getStmt();
+    }
+  }
+  assert(AllocStmt && "Cannot find allocation statement");
 
   PathDiagnosticLocation AllocLocation =
     PathDiagnosticLocation::createBegin(AllocStmt, SMgr,
diff --git a/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
new file mode 100644
index 0000000..a740b7c
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
@@ -0,0 +1,264 @@
+//== TestAfterDivZeroChecker.cpp - Test after division by zero checker --*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines TestAfterDivZeroChecker, a builtin check that performs checks
+//  for division by zero where the division occurs before comparison with zero.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+class ZeroState {
+private:
+  SymbolRef ZeroSymbol;
+  unsigned BlockID;
+  const StackFrameContext *SFC;
+
+public:
+  ZeroState(SymbolRef S, unsigned B, const StackFrameContext *SFC)
+      : ZeroSymbol(S), BlockID(B), SFC(SFC) {}
+
+  const StackFrameContext *getStackFrameContext() const { return SFC; }
+
+  bool operator==(const ZeroState &X) const {
+    return BlockID == X.BlockID && SFC == X.SFC && ZeroSymbol == X.ZeroSymbol;
+  }
+
+  bool operator<(const ZeroState &X) const {
+    if (BlockID != X.BlockID)
+      return BlockID < X.BlockID;
+    if (SFC != X.SFC)
+      return SFC < X.SFC;
+    return ZeroSymbol < X.ZeroSymbol;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(BlockID);
+    ID.AddPointer(SFC);
+    ID.AddPointer(ZeroSymbol);
+  }
+};
+
+class DivisionBRVisitor : public BugReporterVisitorImpl<DivisionBRVisitor> {
+private:
+  SymbolRef ZeroSymbol;
+  const StackFrameContext *SFC;
+  bool Satisfied = false;
+
+public:
+  DivisionBRVisitor(SymbolRef ZeroSymbol, const StackFrameContext *SFC)
+      : ZeroSymbol(ZeroSymbol), SFC(SFC) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    ID.Add(ZeroSymbol);
+    ID.Add(SFC);
+  }
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
+                                 const ExplodedNode *Pred,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
+};
+
+class TestAfterDivZeroChecker
+    : public Checker<check::PreStmt<BinaryOperator>, check::BranchCondition,
+                     check::EndFunction> {
+  mutable std::unique_ptr<BuiltinBug> DivZeroBug;
+  void reportBug(SVal Val, CheckerContext &C) const;
+
+public:
+  void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
+  void checkBranchCondition(const Stmt *Condition, CheckerContext &C) const;
+  void checkEndFunction(CheckerContext &C) const;
+  void setDivZeroMap(SVal Var, CheckerContext &C) const;
+  bool hasDivZeroMap(SVal Var, const CheckerContext &C) const;
+  bool isZero(SVal S, CheckerContext &C) const;
+};
+} // end anonymous namespace
+
+REGISTER_SET_WITH_PROGRAMSTATE(DivZeroMap, ZeroState)
+
+PathDiagnosticPiece *DivisionBRVisitor::VisitNode(const ExplodedNode *Succ,
+                                                  const ExplodedNode *Pred,
+                                                  BugReporterContext &BRC,
+                                                  BugReport &BR) {
+  if (Satisfied)
+    return nullptr;
+
+  const Expr *E = nullptr;
+
+  if (Optional<PostStmt> P = Succ->getLocationAs<PostStmt>())
+    if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>()) {
+      BinaryOperator::Opcode Op = BO->getOpcode();
+      if (Op == BO_Div || Op == BO_Rem || Op == BO_DivAssign ||
+          Op == BO_RemAssign) {
+        E = BO->getRHS();
+      }
+    }
+
+  if (!E)
+    return nullptr;
+
+  ProgramStateRef State = Succ->getState();
+  SVal S = State->getSVal(E, Succ->getLocationContext());
+  if (ZeroSymbol == S.getAsSymbol() && SFC == Succ->getStackFrame()) {
+    Satisfied = true;
+
+    // Construct a new PathDiagnosticPiece.
+    ProgramPoint P = Succ->getLocation();
+    PathDiagnosticLocation L =
+        PathDiagnosticLocation::create(P, BRC.getSourceManager());
+
+    if (!L.isValid() || !L.asLocation().isValid())
+      return nullptr;
+
+    return new PathDiagnosticEventPiece(
+        L, "Division with compared value made here");
+  }
+
+  return nullptr;
+}
+
+bool TestAfterDivZeroChecker::isZero(SVal S, CheckerContext &C) const {
+  Optional<DefinedSVal> DSV = S.getAs<DefinedSVal>();
+
+  if (!DSV)
+    return false;
+
+  ConstraintManager &CM = C.getConstraintManager();
+  return !CM.assume(C.getState(), *DSV, true);
+}
+
+void TestAfterDivZeroChecker::setDivZeroMap(SVal Var, CheckerContext &C) const {
+  SymbolRef SR = Var.getAsSymbol();
+  if (!SR)
+    return;
+
+  ProgramStateRef State = C.getState();
+  State =
+      State->add<DivZeroMap>(ZeroState(SR, C.getBlockID(), C.getStackFrame()));
+  C.addTransition(State);
+}
+
+bool TestAfterDivZeroChecker::hasDivZeroMap(SVal Var,
+                                            const CheckerContext &C) const {
+  SymbolRef SR = Var.getAsSymbol();
+  if (!SR)
+    return false;
+
+  ZeroState ZS(SR, C.getBlockID(), C.getStackFrame());
+  return C.getState()->contains<DivZeroMap>(ZS);
+}
+
+void TestAfterDivZeroChecker::reportBug(SVal Val, CheckerContext &C) const {
+  if (ExplodedNode *N = C.generateSink(C.getState())) {
+    if (!DivZeroBug)
+      DivZeroBug.reset(new BuiltinBug(this, "Division by zero"));
+
+    BugReport *R =
+        new BugReport(*DivZeroBug, "Value being compared against zero has "
+                                   "already been used for division",
+                      N);
+
+    R->addVisitor(new DivisionBRVisitor(Val.getAsSymbol(), C.getStackFrame()));
+    C.emitReport(R);
+  }
+}
+
+void TestAfterDivZeroChecker::checkEndFunction(CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+
+  DivZeroMapTy DivZeroes = State->get<DivZeroMap>();
+  if (DivZeroes.isEmpty())
+    return;
+
+  DivZeroMapTy::Factory &F = State->get_context<DivZeroMap>();
+  for (llvm::ImmutableSet<ZeroState>::iterator I = DivZeroes.begin(),
+                                               E = DivZeroes.end();
+       I != E; ++I) {
+    ZeroState ZS = *I;
+    if (ZS.getStackFrameContext() == C.getStackFrame())
+      DivZeroes = F.remove(DivZeroes, ZS);
+  }
+  C.addTransition(State->set<DivZeroMap>(DivZeroes));
+}
+
+void TestAfterDivZeroChecker::checkPreStmt(const BinaryOperator *B,
+                                           CheckerContext &C) const {
+  BinaryOperator::Opcode Op = B->getOpcode();
+  if (Op == BO_Div || Op == BO_Rem || Op == BO_DivAssign ||
+      Op == BO_RemAssign) {
+    SVal S = C.getSVal(B->getRHS());
+
+    if (!isZero(S, C))
+      setDivZeroMap(S, C);
+  }
+}
+
+void TestAfterDivZeroChecker::checkBranchCondition(const Stmt *Condition,
+                                                   CheckerContext &C) const {
+  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(Condition)) {
+    if (B->isComparisonOp()) {
+      const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(B->getRHS());
+      bool LRHS = true;
+      if (!IntLiteral) {
+        IntLiteral = dyn_cast<IntegerLiteral>(B->getLHS());
+        LRHS = false;
+      }
+
+      if (!IntLiteral || IntLiteral->getValue() != 0)
+        return;
+
+      SVal Val = C.getSVal(LRHS ? B->getLHS() : B->getRHS());
+      if (hasDivZeroMap(Val, C))
+        reportBug(Val, C);
+    }
+  } else if (const UnaryOperator *U = dyn_cast<UnaryOperator>(Condition)) {
+    if (U->getOpcode() == UO_LNot) {
+      SVal Val;
+      if (const ImplicitCastExpr *I =
+              dyn_cast<ImplicitCastExpr>(U->getSubExpr()))
+        Val = C.getSVal(I->getSubExpr());
+
+      if (hasDivZeroMap(Val, C))
+        reportBug(Val, C);
+      else {
+        Val = C.getSVal(U->getSubExpr());
+        if (hasDivZeroMap(Val, C))
+          reportBug(Val, C);
+      }
+    }
+  } else if (const ImplicitCastExpr *IE =
+                 dyn_cast<ImplicitCastExpr>(Condition)) {
+    SVal Val = C.getSVal(IE->getSubExpr());
+
+    if (hasDivZeroMap(Val, C))
+      reportBug(Val, C);
+    else {
+      SVal Val = C.getSVal(Condition);
+
+      if (hasDivZeroMap(Val, C))
+        reportBug(Val, C);
+    }
+  }
+}
+
+void ento::registerTestAfterDivZeroChecker(CheckerManager &mgr) {
+  mgr.registerChecker<TestAfterDivZeroChecker>();
+}
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 38aac28..7944c7e 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -140,8 +140,8 @@
                           /*Default=*/false);
 }
 
-bool AnalyzerOptions::mayInlineCXXContainerCtorsAndDtors() {
-  return getBooleanOption(InlineCXXContainerCtorsAndDtors,
+bool AnalyzerOptions::mayInlineCXXContainerMethods() {
+  return getBooleanOption(InlineCXXContainerMethods,
                           "c++-container-inlining",
                           /*Default=*/false);
 }
@@ -189,6 +189,13 @@
                           /* Default = */ false);
 }
 
+
+bool AnalyzerOptions::shouldWriteStableReportFilename() {
+  return getBooleanOption(StableReportFilename,
+                          "stable-report-filename",
+                          /* Default = */ false);
+}
+
 int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) {
   SmallString<10> StrBuf;
   llvm::raw_svector_ostream OS(StrBuf);
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 6c7cb23..141a48b 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -125,7 +125,7 @@
           break;
         
         if (PathDiagnosticEventPiece *nextEvent =
-            dyn_cast<PathDiagnosticEventPiece>(path.front().getPtr())) {
+            dyn_cast<PathDiagnosticEventPiece>(path.front().get())) {
           PathDiagnosticEventPiece *event =
             cast<PathDiagnosticEventPiece>(piece);
           // Check to see if we should keep one of the two pieces.  If we
@@ -1412,7 +1412,7 @@
       if (Optional<PostStmt> PS = P.getAs<PostStmt>()) {
         if (const Expr *Ex = PS->getStmtAs<Expr>())
           reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
-                                              N->getState().getPtr(), Ex,
+                                              N->getState().get(), Ex,
                                               N->getLocationContext());
       }
       
@@ -1420,7 +1420,7 @@
         const Stmt *S = CE->getCalleeContext()->getCallSite();
         if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
             reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
-                                                N->getState().getPtr(), Ex,
+                                                N->getState().get(), Ex,
                                                 N->getLocationContext());
         }
         
@@ -1491,7 +1491,7 @@
           const LocationContext *CalleeCtx = PDB.LC;
           if (CallerCtx != CalleeCtx) {
             reversePropagateInterestingSymbols(*PDB.getBugReport(), IE,
-                                               N->getState().getPtr(),
+                                               N->getState().get(),
                                                CalleeCtx, CallerCtx);
           }
         }
@@ -1674,7 +1674,7 @@
 
         PathDiagnosticCallPiece *C;
         if (VisitedEntireCall) {
-          PathDiagnosticPiece *P = PD.getActivePath().front().getPtr();
+          PathDiagnosticPiece *P = PD.getActivePath().front().get();
           C = cast<PathDiagnosticCallPiece>(P);
         } else {
           const Decl *Caller = CE->getLocationContext()->getDecl();
@@ -1728,7 +1728,7 @@
         // Propagate the interesting symbols accordingly.
         if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
           reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
-                                              N->getState().getPtr(), Ex,
+                                              N->getState().get(), Ex,
                                               N->getLocationContext());
         }
 
@@ -1756,7 +1756,7 @@
         // interesting symbols correctly.
         if (const Expr *Ex = PS->getStmtAs<Expr>())
           reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
-                                              N->getState().getPtr(), Ex,
+                                              N->getState().get(), Ex,
                                               N->getLocationContext());
 
         // Add an edge.  If this is an ObjCForCollectionStmt do
@@ -1779,7 +1779,7 @@
           const LocationContext *CalleeCtx = PDB.LC;
           if (CallerCtx != CalleeCtx) {
             reversePropagateInterestingSymbols(*PDB.getBugReport(), IE,
-                                               N->getState().getPtr(),
+                                               N->getState().get(),
                                                CalleeCtx, CallerCtx);
           }
         }
@@ -2995,7 +2995,7 @@
   for (PathPieces::const_iterator I = path.begin(), E = path.end();
        I!=E; ++I) {
     
-    PathDiagnosticPiece *piece = I->getPtr();
+    PathDiagnosticPiece *piece = I->get();
 
     // Recursively compact calls.
     if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index b415d5b..0503ace 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -724,7 +724,7 @@
 bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const {
   if (IsZeroCheck)
     return N->getState()->isNull(Constraint).isUnderconstrained();
-  return N->getState()->assume(Constraint, !Assumption);
+  return (bool)N->getState()->assume(Constraint, !Assumption);
 }
 
 PathDiagnosticPiece *
@@ -1285,13 +1285,13 @@
     if (quotes) {
       Out << '\'';
       const LocationContext *LCtx = N->getLocationContext();
-      const ProgramState *state = N->getState().getPtr();
+      const ProgramState *state = N->getState().get();
       if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
                                                 LCtx).getAsRegion()) {
         if (report.isInteresting(R))
           prunable = false;
         else {
-          const ProgramState *state = N->getState().getPtr();
+          const ProgramState *state = N->getState().get();
           SVal V = state->getSVal(R);
           if (report.isInteresting(V))
             prunable = false;
@@ -1446,7 +1446,7 @@
 
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
-      const ProgramState *state = N->getState().getPtr();
+      const ProgramState *state = N->getState().get();
       if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
         if (report.isInteresting(R))
           event->setPrunable(false);
@@ -1490,7 +1490,7 @@
   PathDiagnosticEventPiece *event =
     new PathDiagnosticEventPiece(Loc, Out.str());
   
-  const ProgramState *state = N->getState().getPtr();
+  const ProgramState *state = N->getState().get();
   if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
     if (report.isInteresting(R))
       event->setPrunable(false);
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index a02e413..7e0670a 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -311,7 +311,7 @@
 ArrayRef<ParmVarDecl*> AnyFunctionCall::parameters() const {
   const FunctionDecl *D = getDecl();
   if (!D)
-    return llvm::ArrayRef<ParmVarDecl*>();
+    return None;
   return D->parameters();
 }
 
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index e710c7f..4623c35 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -541,7 +541,7 @@
   CFGStmt CS = (*Block)[Idx].castAs<CFGStmt>();
   PostStmt Loc(CS.getStmt(), N->getLocationContext());
 
-  if (Loc == N->getLocation()) {
+  if (Loc == N->getLocation().withTag(nullptr)) {
     // Note: 'N' should be a fresh node because otherwise it shouldn't be
     // a member of Deferred.
     WList->enqueue(N, Block, Idx+1);
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp
index 6a26650..ae5a4cc 100644
--- a/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/lib/StaticAnalyzer/Core/Environment.cpp
@@ -205,7 +205,8 @@
     }
     
     const Stmt *S = En.getStmt();
-    
+    assert(S != nullptr && "Expected non-null Stmt");
+
     Out << " (" << (const void*) En.getLocationContext() << ','
       << (const void*) S << ") ";
     LangOptions LO; // FIXME.
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index ac87d58..9b7e746 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -699,6 +699,7 @@
     case Stmt::FunctionParmPackExprClass:
     case Stmt::SEHTryStmtClass:
     case Stmt::SEHExceptStmtClass:
+    case Stmt::SEHLeaveStmtClass:
     case Stmt::LambdaExprClass:
     case Stmt::SEHFinallyStmtClass: {
       const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
@@ -732,6 +733,12 @@
     case Stmt::CapturedStmtClass:
     case Stmt::OMPParallelDirectiveClass:
     case Stmt::OMPSimdDirectiveClass:
+    case Stmt::OMPForDirectiveClass:
+    case Stmt::OMPSectionsDirectiveClass:
+    case Stmt::OMPSectionDirectiveClass:
+    case Stmt::OMPSingleDirectiveClass:
+    case Stmt::OMPParallelForDirectiveClass:
+    case Stmt::OMPParallelSectionsDirectiveClass:
       llvm_unreachable("Stmt should not be in analyzer evaluation loop");
 
     case Stmt::ObjCSubscriptRefExprClass:
@@ -2252,9 +2259,8 @@
 
   ProgramStateRef state = Pred->getState();
 
-  for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(),
-       OE = A->end_outputs(); OI != OE; ++OI) {
-    SVal X = state->getSVal(*OI, Pred->getLocationContext());
+  for (const Expr *O : A->outputs()) {
+    SVal X = state->getSVal(O, Pred->getLocationContext());
     assert (!X.getAs<NonLoc>());  // Should be an Lval, or unknown, undef.
 
     if (Optional<Loc> LV = X.getAs<Loc>())
@@ -2428,7 +2434,8 @@
               if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
                 Out << "\\lcase ";
                 LangOptions LO; // FIXME.
-                C->getLHS()->printPretty(Out, nullptr, PrintingPolicy(LO));
+                if (C->getLHS())
+                  C->getLHS()->printPretty(Out, nullptr, PrintingPolicy(LO));
 
                 if (const Stmt *RHS = C->getRHS()) {
                   Out << " .. ";
@@ -2471,6 +2478,7 @@
 
       default: {
         const Stmt *S = Loc.castAs<StmtPoint>().getStmt();
+        assert(S != nullptr && "Expecting non-null Stmt");
 
         Out << S->getStmtClassName() << ' ' << (const void*) S << ' ';
         LangOptions LO; // FIXME.
@@ -2512,7 +2520,7 @@
     }
 
     ProgramStateRef state = N->getState();
-    Out << "\\|StateID: " << (const void*) state.getPtr()
+    Out << "\\|StateID: " << (const void*) state.get()
         << " NodeID: " << (const void*) N << "\\|";
     state->printDOT(Out);
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 4619f62..3f608ba 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -708,18 +708,16 @@
          hasMember(Ctx, RD, "iterator_category");
 }
 
-/// Returns true if the given function refers to a constructor or destructor of
-/// a C++ container or iterator.
+/// Returns true if the given function refers to a method of a C++ container
+/// or iterator.
 ///
-/// We generally do a poor job modeling most containers right now, and would
-/// prefer not to inline their setup and teardown.
-static bool isContainerCtorOrDtor(const ASTContext &Ctx,
-                                  const FunctionDecl *FD) {
-  if (!(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD)))
-    return false;
-
-  const CXXRecordDecl *RD = cast<CXXMethodDecl>(FD)->getParent();
-  return isContainerClass(Ctx, RD);
+/// We generally do a poor job modeling most containers right now, and might
+/// prefer not to inline their methods.
+static bool isContainerMethod(const ASTContext &Ctx,
+                              const FunctionDecl *FD) {
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
+    return isContainerClass(Ctx, MD->getParent());
+  return false;
 }
 
 /// Returns true if the given function is the destructor of a class named
@@ -765,9 +763,9 @@
 
       // Conditionally control the inlining of methods on objects that look
       // like C++ containers.
-      if (!Opts.mayInlineCXXContainerCtorsAndDtors())
+      if (!Opts.mayInlineCXXContainerMethods())
         if (!Ctx.getSourceManager().isInMainFile(FD->getLocation()))
-          if (isContainerCtorOrDtor(Ctx, FD))
+          if (isContainerMethod(Ctx, FD))
             return false;
             
       // Conditionally control the inlining of the destructor of C++ shared_ptr.
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index e8ec005..b1e9f06c 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -20,11 +20,13 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Rewrite/Core/HTMLRewrite.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
+#include <sstream>
 
 using namespace clang;
 using namespace ento;
@@ -39,8 +41,9 @@
   std::string Directory;
   bool createdDir, noDir;
   const Preprocessor &PP;
+  AnalyzerOptions &AnalyzerOpts;
 public:
-  HTMLDiagnostics(const std::string& prefix, const Preprocessor &pp);
+  HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string& prefix, const Preprocessor &pp);
 
   virtual ~HTMLDiagnostics() { FlushDiagnostics(nullptr); }
 
@@ -68,16 +71,17 @@
 
 } // end anonymous namespace
 
-HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix,
+HTMLDiagnostics::HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts,
+                                 const std::string& prefix,
                                  const Preprocessor &pp)
-  : Directory(prefix), createdDir(false), noDir(false), PP(pp) {
+    : Directory(prefix), createdDir(false), noDir(false), PP(pp), AnalyzerOpts(AnalyzerOpts) {
 }
 
 void ento::createHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
                                         PathDiagnosticConsumers &C,
                                         const std::string& prefix,
                                         const Preprocessor &PP) {
-  C.push_back(new HTMLDiagnostics(prefix, PP));
+  C.push_back(new HTMLDiagnostics(AnalyzerOpts, prefix, PP));
 }
 
 //===----------------------------------------------------------------------===//
@@ -95,11 +99,11 @@
 
 void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
                                  FilesMade *filesMade) {
-    
+
   // Create the HTML directory if it is missing.
   if (!createdDir) {
     createdDir = true;
-    if (llvm::error_code ec = llvm::sys::fs::create_directories(Directory)) {
+    if (std::error_code ec = llvm::sys::fs::create_directories(Directory)) {
       llvm::errs() << "warning: could not create directory '"
                    << Directory << "': " << ec.message() << '\n';
 
@@ -126,11 +130,30 @@
   // Create a new rewriter to generate HTML.
   Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOpts());
 
+  // 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)) {
+          declName = ND->getDeclName().getAsString();
+      }
+
+      if (const Stmt *Body = DeclWithIssue->getBody()) {
+          // Retrieve the relative position of the declaration which will be used
+          // for the file name
+          FullSourceLoc L(
+              SMgr.getExpansionLoc((*path.rbegin())->getLocation().asLocation()),
+              SMgr);
+          FullSourceLoc FunL(SMgr.getExpansionLoc(Body->getLocStart()), SMgr);
+          offsetDecl = L.getExpansionLineNumber() - FunL.getExpansionLineNumber();
+      }
+  }
+
   // Process the path.
   unsigned n = path.size();
   unsigned max = n;
 
-  for (PathPieces::const_reverse_iterator I = path.rbegin(), 
+  for (PathPieces::const_reverse_iterator I = path.rbegin(),
        E = path.rend();
         I != E; ++I, --n)
     HandlePiece(R, FID, **I, n, max);
@@ -163,6 +186,9 @@
     DirName += '/';
   }
 
+  int LineNumber = (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber();
+  int ColumnNumber = (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber();
+
   // Add the name of the file as an <h1> tag.
 
   {
@@ -176,9 +202,9 @@
       << html::EscapeText(Entry->getName())
       << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
          "<a href=\"#EndPath\">line "
-      << (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber()
+      << LineNumber
       << ", column "
-      << (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber()
+      << ColumnNumber
       << "</a></td></tr>\n"
          "<tr><td class=\"rowname\">Description:</td><td>"
       << D.getVerboseDescription() << "</td></tr>\n";
@@ -215,12 +241,16 @@
 
     os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
 
+    os << "\n<!-- FILENAME " << llvm::sys::path::filename(Entry->getName()) << " -->\n";
+
+    os  << "\n<!-- FUNCTIONNAME " <<  declName << " -->\n";
+
     os << "\n<!-- BUGLINE "
-       << path.back()->getLocation().asLocation().getExpansionLineNumber()
+       << LineNumber
        << " -->\n";
 
     os << "\n<!-- BUGCOLUMN "
-      << path.back()->getLocation().asLocation().getExpansionColumnNumber()
+      << ColumnNumber
       << " -->\n";
 
     os << "\n<!-- BUGPATHLENGTH " << path.size() << " -->\n";
@@ -247,13 +277,42 @@
   // Create a path for the target HTML file.
   int FD;
   SmallString<128> Model, ResultPath;
-  llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
 
-  if (llvm::error_code EC =
+  if (!AnalyzerOpts.shouldWriteStableReportFilename()) {
+      llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
+
+      if (std::error_code EC =
           llvm::sys::fs::createUniqueFile(Model.str(), FD, ResultPath)) {
-    llvm::errs() << "warning: could not create file in '" << Directory
-                 << "': " << EC.message() << '\n';
-    return;
+          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
+          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.str(),
+                                               FD,
+                                               llvm::sys::fs::F_RW |
+                                               llvm::sys::fs::F_Excl);
+          if (EC && EC != std::errc::file_exists) {
+              llvm::errs() << "warning: could not create file '" << Model.str()
+                           << "': " << EC.message() << '\n';
+              return;
+          }
+          i++;
+      } while (EC);
   }
 
   llvm::raw_fd_ostream os(FD, true);
@@ -458,7 +517,7 @@
            << (num + 1)
            << ")\">&#x2192;</a></div></td>";
       }
-      
+
       os << "</tr></table>";
     }
   }
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index 12bbfdf..22711f5 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -508,10 +508,12 @@
 }
 
 void StringRegion::dumpToStream(raw_ostream &os) const {
+  assert(Str != nullptr && "Expecting non-null StringLiteral");
   Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
 }
 
 void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
+  assert(Str != nullptr && "Expecting non-null ObjCStringLiteral");
   Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
 }
 
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index a9527de..fd25bd8 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -67,7 +67,7 @@
 void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current,
                            bool ShouldFlattenMacros) const {
   for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
-    PathDiagnosticPiece *Piece = I->getPtr();
+    PathDiagnosticPiece *Piece = I->get();
 
     switch (Piece->getKind()) {
     case PathDiagnosticPiece::Call: {
@@ -157,7 +157,7 @@
   if (path.empty())
     return;
 
-  PathDiagnosticPiece *LastP = path.back().getPtr();
+  PathDiagnosticPiece *LastP = path.back().get();
   assert(LastP);
   const SourceManager &SMgr = LastP->getLocation().getManager();
 
@@ -222,7 +222,7 @@
 
       for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E;
            ++I) {
-        const PathDiagnosticPiece *piece = I->getPtr();
+        const PathDiagnosticPiece *piece = I->get();
         FullSourceLoc L = piece->getLocation().asLocation().getExpansionLoc();
       
         if (FID.isInvalid()) {
@@ -1037,7 +1037,7 @@
 static void compute_path_size(const PathPieces &pieces, unsigned &size) {
   for (PathPieces::const_iterator it = pieces.begin(),
                                   et = pieces.end(); it != et; ++it) {
-    const PathDiagnosticPiece *piece = it->getPtr();
+    const PathDiagnosticPiece *piece = it->get();
     if (const PathDiagnosticCallPiece *cp = 
         dyn_cast<PathDiagnosticCallPiece>(piece)) {
       compute_path_size(cp->path, size);
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index 2585e54..ba3ad2e 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -173,8 +173,8 @@
   }
   
   // Output the call depth.
-  Indent(o, indent) << "<key>depth</key>"
-                    << "<integer>" << depth << "</integer>\n";
+  Indent(o, indent) << "<key>depth</key>";
+  EmitInteger(o, depth) << '\n';
 
   // Output the text.
   assert(!P.getString().empty());
@@ -311,7 +311,7 @@
 
       for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E;
            ++I) {
-        const PathDiagnosticPiece *piece = I->getPtr();
+        const PathDiagnosticPiece *piece = I->get();
         AddFID(FM, Fids, *SM, piece->getLocation().asLocation());
         ArrayRef<SourceRange> Ranges = piece->getRanges();
         for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
@@ -345,8 +345,7 @@
     return;
   }
 
-  // Write the plist header.
-  o << PlistHeader;
+  EmitPlistHeader(o);
 
   // Write the root object: a <dict> containing...
   //  - "clang_version", the string representation of clang version
@@ -358,11 +357,8 @@
   o << " <key>files</key>\n"
        " <array>\n";
 
-  for (SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end();
-       I!=E; ++I) {
-    o << "  ";
-    EmitString(o, SM->getFileEntryForID(*I)->getName()) << '\n';
-  }
+  for (FileID FID : Fids)
+    EmitString(o << "  ", SM->getFileEntryForID(FID)->getName()) << '\n';
 
   o << " </array>\n"
        " <key>diagnostics</key>\n"
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index ccaa8b6..12e514b 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -214,7 +214,7 @@
         default:
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)                    \
   case PD_##NAME:                                                              \
-    CREATEFN(*Opts.getPtr(), PathConsumers, OutDir, PP);                       \
+    CREATEFN(*Opts.get(), PathConsumers, OutDir, PP);                       \
     break;
 #include "clang/StaticAnalyzer/Core/Analyses.def"
         }
diff --git a/lib/Tooling/CompilationDatabase.cpp b/lib/Tooling/CompilationDatabase.cpp
index 94bdc8d..4b776bf 100644
--- a/lib/Tooling/CompilationDatabase.cpp
+++ b/lib/Tooling/CompilationDatabase.cpp
@@ -27,8 +27,8 @@
 #include "llvm/Option/Arg.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/system_error.h"
 #include <sstream>
+#include <system_error>
 
 namespace clang {
 namespace tooling {
diff --git a/lib/Tooling/JSONCompilationDatabase.cpp b/lib/Tooling/JSONCompilationDatabase.cpp
index bba71f2..8b8bd29 100644
--- a/lib/Tooling/JSONCompilationDatabase.cpp
+++ b/lib/Tooling/JSONCompilationDatabase.cpp
@@ -17,7 +17,7 @@
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 
 namespace clang {
 namespace tooling {
@@ -144,15 +144,14 @@
 JSONCompilationDatabase *
 JSONCompilationDatabase::loadFromFile(StringRef FilePath,
                                       std::string &ErrorMessage) {
-  std::unique_ptr<llvm::MemoryBuffer> DatabaseBuffer;
-  llvm::error_code Result =
-    llvm::MemoryBuffer::getFile(FilePath, DatabaseBuffer);
-  if (Result != nullptr) {
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> DatabaseBuffer =
+      llvm::MemoryBuffer::getFile(FilePath);
+  if (std::error_code Result = DatabaseBuffer.getError()) {
     ErrorMessage = "Error while opening JSON database: " + Result.message();
     return nullptr;
   }
   std::unique_ptr<JSONCompilationDatabase> Database(
-      new JSONCompilationDatabase(DatabaseBuffer.release()));
+      new JSONCompilationDatabase(DatabaseBuffer->release()));
   if (!Database->parse(ErrorMessage))
     return nullptr;
   return Database.release();
diff --git a/lib/Tooling/Refactoring.cpp b/lib/Tooling/Refactoring.cpp
index 4b4056b..c96b8c9 100644
--- a/lib/Tooling/Refactoring.cpp
+++ b/lib/Tooling/Refactoring.cpp
@@ -110,7 +110,7 @@
     // Make FilePath absolute so replacements can be applied correctly when
     // relative paths for files are used.
     llvm::SmallString<256> FilePath(Entry->getName());
-    llvm::error_code EC = llvm::sys::fs::make_absolute(FilePath);
+    std::error_code EC = llvm::sys::fs::make_absolute(FilePath);
     this->FilePath = EC ? FilePath.c_str() : Entry->getName();
   } else {
     this->FilePath = InvalidLocation;
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index 35e3eb4..0db38db 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -24,7 +24,7 @@
 #include "clang/Tooling/ArgumentsAdjusters.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Option/Option.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileSystem.h"
@@ -129,7 +129,7 @@
   llvm::IntrusiveRefCntPtr<FileManager> Files(
       new FileManager(FileSystemOptions()));
   ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), ToolAction,
-                            Files.getPtr());
+                            Files.get());
 
   SmallString<1024> CodeStorage;
   Invocation.mapVirtualFile(FileNameRef,
@@ -145,7 +145,7 @@
   }
 
   SmallString<1024> AbsolutePath = RelativePath;
-  llvm::error_code EC = llvm::sys::fs::make_absolute(AbsolutePath);
+  std::error_code EC = llvm::sys::fs::make_absolute(AbsolutePath);
   assert(!EC);
   (void)EC;
   llvm::sys::path::native(AbsolutePath);
@@ -352,7 +352,7 @@
     DEBUG({
       llvm::dbgs() << "Processing: " << Command.first << ".\n";
     });
-    ToolInvocation Invocation(std::move(CommandLine), Action, Files.getPtr());
+    ToolInvocation Invocation(std::move(CommandLine), Action, Files.get());
     Invocation.setDiagnosticConsumer(DiagConsumer);
     for (const auto &MappedFile : MappedFileContents) {
       Invocation.mapVirtualFile(MappedFile.first, MappedFile.second);
diff --git a/test/ARCMT/objcmt-arc-cf-annotations.m b/test/ARCMT/objcmt-arc-cf-annotations.m
index 1e063f6..c9a5b82 100644
--- a/test/ARCMT/objcmt-arc-cf-annotations.m
+++ b/test/ARCMT/objcmt-arc-cf-annotations.m
@@ -528,38 +528,54 @@
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
-    CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
-    CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
-    CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+  switch (x) {
+  case 0:
+    CFRelease(p);
+    break;
+  case 1:
+    CFRetain(p);
+    break;
+  case 2:
+    CFMakeCollectable(p);
+    break;
+  case 3:
+    CFAutorelease(p);
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
diff --git a/test/ARCMT/objcmt-arc-cf-annotations.m.result b/test/ARCMT/objcmt-arc-cf-annotations.m.result
index 75dda6c..84bc43d 100644
--- a/test/ARCMT/objcmt-arc-cf-annotations.m.result
+++ b/test/ARCMT/objcmt-arc-cf-annotations.m.result
@@ -570,38 +570,54 @@
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
-    CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
-    CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
-    CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+  switch (x) {
+  case 0:
+    CFRelease(p);
+    break;
+  case 1:
+    CFRetain(p);
+    break;
+  case 2:
+    CFMakeCollectable(p);
+    break;
+  case 3:
+    CFAutorelease(p);
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
diff --git a/test/Analysis/diagnostics/undef-value-param.m b/test/Analysis/diagnostics/undef-value-param.m
index e977acb..b0ce56c 100644
--- a/test/Analysis/diagnostics/undef-value-param.m
+++ b/test/Analysis/diagnostics/undef-value-param.m
@@ -542,7 +542,7 @@
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRelease</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>5</string>
diff --git a/test/Analysis/inlining/containers.cpp b/test/Analysis/inlining/containers.cpp
index 73b2957..c757da6 100644
--- a/test/Analysis/inlining/containers.cpp
+++ b/test/Analysis/inlining/containers.cpp
@@ -103,7 +103,10 @@
   ~MySet() { delete[] storage; }
 
   bool isEmpty() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return size == 0;
   }
 
@@ -114,23 +117,35 @@
   };
 
   iterator begin() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return iterator(storage);
   }
 
   iterator end() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return iterator(storage+size);
   }
 
   typedef int *raw_iterator;
 
   raw_iterator raw_begin() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return storage;
   }
   raw_iterator raw_end() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return storage + size;
   }
 };
@@ -145,7 +160,10 @@
   }
 
   void useIterator(iterator i) {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
   }
 };
 
@@ -174,7 +192,10 @@
   typedef IterImpl wrapped_iterator;
 
   wrapped_iterator begin() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return IterImpl(impl.begin());
   }
 };
@@ -193,7 +214,10 @@
   typedef MySet::iterator iterator;
 
   iterator start() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+#if INLINE
+    // expected-warning@-2 {{TRUE}}
+#endif
     return impl.begin();
   }
 };
@@ -212,7 +236,10 @@
   using iterator = MySet::iterator;
 
   iterator start() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return impl.begin();
   }
 };
@@ -233,7 +260,10 @@
   };
 
   iterator start() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return iterator{impl.begin().impl};
   }
 };
diff --git a/test/Analysis/inlining/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp
index afbdf21..1e23074 100644
--- a/test/Analysis/inlining/path-notes.cpp
+++ b/test/Analysis/inlining/path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist -Wno-tautological-undefined-compare
 // RUN: FileCheck --input-file=%t.plist %s
 
 class Foo {
@@ -2452,12 +2452,12 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>105</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
+// CHECK-NEXT:            <key>col</key><integer>53</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>105</integer>
-// CHECK-NEXT:            <key>col</key><integer>28</integer>
+// CHECK-NEXT:            <key>col</key><integer>53</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -2469,7 +2469,7 @@
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
 // CHECK-NEXT:       <key>line</key><integer>105</integer>
-// CHECK-NEXT:       <key>col</key><integer>21</integer>
+// CHECK-NEXT:       <key>col</key><integer>53</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:      <key>ranges</key>
@@ -2477,12 +2477,12 @@
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>105</integer>
-// CHECK-NEXT:          <key>col</key><integer>21</integer>
+// CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>105</integer>
-// CHECK-NEXT:          <key>col</key><integer>28</integer>
+// CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index cb51042..af9f7cf 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
 
 void clang_analyzer_warnIfReached();
 
diff --git a/test/Analysis/objc-radar17039661.m b/test/Analysis/objc-radar17039661.m
new file mode 100644
index 0000000..ec4f19d
--- /dev/null
+++ b/test/Analysis/objc-radar17039661.m
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify -fblocks %s
+
+@class NSString;
+typedef long NSInteger;
+typedef unsigned char BOOL;
+@interface NSObject {}
++(id)alloc;
+-(id)init;
+-(id)autorelease;
+-(id)copy;
+-(id)retain;
+@end
+@interface NSNumber : NSObject
++ (NSNumber *)numberWithInteger:(NSInteger)value __attribute__((availability(ios,introduced=2.0)));
+@end
+
+NSInteger *inoutIntegerValueGlobal;
+NSInteger *inoutIntegerValueGlobal2;
+NSString *traitNameGlobal;
+static BOOL cond;
+
+static inline void reallyPerformAction(void (^integerHandler)(NSInteger *inoutIntegerValue, NSString *traitName)) {
+  integerHandler(inoutIntegerValueGlobal, traitNameGlobal);
+  integerHandler(inoutIntegerValueGlobal2,traitNameGlobal);
+}
+
+static inline BOOL performAction(NSNumber *(^action)(NSNumber *traitValue)) {
+  __attribute__((__blocks__(byref))) BOOL didFindTrait = 0;
+  reallyPerformAction(^(NSInteger *inoutIntegerValue,NSString *traitName) {
+
+    if (cond) {
+
+      NSNumber *traitValue = @(*inoutIntegerValue);
+
+      NSNumber *newTraitValue = action(traitValue);
+
+      if (traitValue != newTraitValue) {
+        *inoutIntegerValue = newTraitValue ? *inoutIntegerValue : *inoutIntegerValue;
+      }
+      didFindTrait = 1;
+    }
+
+  });
+  return didFindTrait;
+}
+
+void runTest() {
+  __attribute__((__blocks__(byref))) NSNumber *builtinResult = ((NSNumber *)0);
+  BOOL wasBuiltinTrait = performAction(^(NSNumber *traitValue) {
+    builtinResult = [traitValue retain]; // expected-warning {{Potential leak of an object}}
+
+    return traitValue;
+  });
+  if (wasBuiltinTrait) {
+    [builtinResult autorelease];
+    return;
+  } else {
+    return;
+  }
+}
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index bd5eaaa..cd0202e 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference -Wno-tautological-undefined-compare %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/retain-release-cache-out.m b/test/Analysis/retain-release-cache-out.m
new file mode 100644
index 0000000..54573a4
--- /dev/null
+++ b/test/Analysis/retain-release-cache-out.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -analyze %s -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify
+
+// This test is checking behavior when a single checker runs only with the core
+// checkers, testing that the traversal order in the CFG does not affect the
+// reporting of an error.
+
+#import "Inputs/system-header-simulator-objc.h"
+
+void testDoubleRelease(BOOL z) {
+  id x = [[NSObject alloc] init];
+  if (z) {
+    [x release];
+  } else {
+    ;
+  }
+  [x release]; // expected-warning {{Reference-counted object is used after it is released}}
+}
+
+void testDoubleRelease2(BOOL z) {
+  id x = [[NSObject alloc] init];
+  if (z) {
+    ;
+  } else {
+    [x release];
+  }
+  [x release]; // expected-warning {{Reference-counted object is used after it is released}}
+}
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index afe997b..6973f9b 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -523,38 +523,54 @@
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+    break;
+  case 3:
+    CFAutorelease(p); // expected-warning{{Null pointer argument in call to CFAutorelease}}
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
@@ -9501,7 +9517,7 @@
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRelease</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>5</string>
@@ -9838,7 +9854,7 @@
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRetain</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>8</string>
@@ -10175,7 +10191,7 @@
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFMakeCollectable</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>11</string>
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
index a39f9c7..a4ab2f3 100644
--- a/test/Analysis/stack-addr-ps.cpp
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s -Wno-undefined-bool-conversion
 
 typedef __INTPTR_TYPE__ intptr_t;
 
diff --git a/test/Analysis/test-after-div-zero.c b/test/Analysis/test-after-div-zero.c
new file mode 100644
index 0000000..f34c4f7
--- /dev/null
+++ b/test/Analysis/test-after-div-zero.c
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -std=c99 -Dbool=_Bool -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
+// RUN: %clang_cc1 -x c++ -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
+
+int var;
+
+void err_eq(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x == 0) { } // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_eq2(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (0 == x) { } // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_ne(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x != 0) { } // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_ge(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x >= 0) { } // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_le(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x <= 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_yes(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+void err_not(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_pnot(int x) {
+  int *y = &x;
+  var = 77 / *y; // expected-note {{Division with compared value made here}}
+  if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_pnot2(int x) {
+  int *y = &x;
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (!*y) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_ppnot(int x) {
+  int *y = &x;
+  int **z = &y;
+  var = 77 / **z; // expected-note {{Division with compared value made here}}
+  if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_orig_checker(int x) {
+  if (x != 0) // expected-note {{Assuming 'x' is equal to 0}} expected-note {{Taking false branch}}
+    return;
+  var = 77 / x; // expected-warning {{Division by zero}} expected-note {{Division by zero}}
+  if (!x) {} // no-warning
+}
+
+void ok_other(int x, int y) {
+  var = 77 / y;
+  if (x == 0) {
+  }
+}
+
+void ok_assign(int x) {
+  var = 77 / x;
+  x = var / 77; // <- assignment => don't warn
+  if (x == 0) {
+  }
+}
+
+void ok_assign2(int x) {
+  var = 77 / x;
+  x = var / 77; // <- assignment => don't warn
+  if (0 == x) {
+  }
+}
+
+void ok_dec(int x) {
+  var = 77 / x;
+  x--; // <- assignment => don't warn
+  if (x == 0) {
+  }
+}
+
+void ok_inc(int x) {
+  var = 77 / x;
+  x++; // <- assignment => don't warn
+  if (x == 0) {
+  }
+}
+
+void do_something_ptr(int *x);
+void ok_callfunc_ptr(int x) {
+  var = 77 / x;
+  do_something_ptr(&x); // <- pass address of x to function => don't warn
+  if (x == 0) {
+  }
+}
+
+void do_something(int x);
+void nok_callfunc(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  do_something(x);
+  if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void ok_if(int x) {
+  if (x > 3)
+    var = 77 / x;
+  if (x == 0) {
+  }
+}
+
+void ok_if2(int x) {
+  if (x < 3)
+    var = 77 / x;
+  if (x == 0) {
+  } // TODO warn here
+}
+
+void ok_pif(int x) {
+  int *y = &x;
+  if (x < 3)
+    var = 77 / *y;
+  if (x == 0) {
+  } // TODO warn here
+}
+
+int getValue(bool *isPositive);
+void use(int a);
+void foo() {
+  bool isPositive;
+  int x = getValue(&isPositive);
+  if (isPositive) {
+    use(5 / x);
+  }
+
+  if (x == 0) {
+  }
+}
+
+int getValue2();
+void foo2() {
+  int x = getValue2();
+  int y = x;
+
+  use(5 / x); // expected-note {{Division with compared value made here}}
+  if (y == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void ok_while(int x) {
+  int n = 100 / x;
+  while (x != 0) { // <- do not warn
+    x--;
+  }
+}
+
+void err_not2(int x, int y) {
+  int v;
+  var = 77 / x;
+
+  if (y)
+    v = 0;
+
+  if (!x) {
+  } // TODO warn here
+}
+
+inline void inline_func(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_inline(int x) {
+  var = 77 / x;
+  inline_func(x); // expected-note {{Calling 'inline_func'}}
+  if (x == 0) {
+  }
+}
+
+inline void inline_func2(int x) {}
+
+void err_inline2(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  inline_func2(x);
+  if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+inline void inline_func3(int x) {
+  var = 77 / x;
+}
+void ok_inline(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  inline_func3(x);
+  if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 66a8cab..fe80df4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -29,10 +29,16 @@
   c-index-test diagtool arcmt-test c-arcmt-test
   clang-check clang-format
   clang-tblgen
-  clang-interpreter
-  PrintFunctionNames
-  SampleAnalyzerPlugin
   )
+
+if (ENABLE_CLANG_EXAMPLES)
+  list(APPEND CLANG_TEST_DEPS
+    clang-interpreter
+    PrintFunctionNames
+    SampleAnalyzerPlugin
+    )
+endif ()
+
 set(CLANG_TEST_PARAMS
   clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
   )
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
index c745c84..c3be712 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
@@ -1,26 +1,25 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-// XFAIL: *
-// Our C++0x doesn't currently have specialized destructor name handling,
-// since the specification is still in flux.
-struct C { 
-  typedef int I;
-}; 
+// expected-no-diagnostics
 
-typedef int I1, I2; 
-extern int* p; 
-extern int* q; 
+struct C {
+  typedef int I;
+};
+
+typedef int I1, I2;
+extern int* p;
+extern int* q;
 
 void f() {
-  p->C::I::~I(); 
+  p->C::I::~I();
   q->I1::~I2();
 }
 
-struct A { 
+struct A {
   ~A();
-}; 
+};
 
-typedef A AB; 
+typedef A AB;
 int main() {
-  AB *p; 
+  AB *p;
   p->AB::~AB();
 }
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
index 253d15e..c59c4a5 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// XFAIL: *
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
 
 class C {
 public:
@@ -10,8 +9,13 @@
      int b) // expected-note {{previous definition}}
 try {
   int c;
-
 } catch (int a) { // expected-error {{redefinition of 'a'}}
   int b; // expected-error {{redefinition of 'b'}}
   ++c; // expected-error {{use of undeclared identifier 'c'}}
 }
+
+void f(int i) {
+  struct S {
+    void g() try {} catch (int i) {}; // OK
+  };
+}
diff --git a/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp b/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
index 7c7b84d..1b41991 100644
--- a/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
+++ b/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
@@ -9,8 +9,8 @@
 } catch (...) {
 }
 
-void func3(int i) try { // FIXME: note {{previous definition is here}}
-} catch (int i) { // FIXME: error {{redefinition of 'i'}}
+void func3(int i) try { // expected-note {{previous definition is here}}
+} catch (int i) { // expected-error {{redefinition of 'i'}}
 }
 
 void func4(int i) try { // expected-note{{previous definition is here}}
@@ -58,3 +58,9 @@
       int b; // FIXME: decide whether this is valid
     }
 }
+
+void func11(int a) {
+  try {
+  } catch (int a) {  // OK
+  }
+}
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2.cpp b/test/CXX/basic/basic.start/basic.start.main/p2.cpp
index 5c7d60c..42e87e5 100644
--- a/test/CXX/basic/basic.start/basic.start.main/p2.cpp
+++ b/test/CXX/basic/basic.start/basic.start.main/p2.cpp
@@ -62,6 +62,8 @@
 ) {
 }
 
+const int main(); // expected-error {{'main' must return 'int'}}
+
 #elif TEST7
 
 // expected-no-diagnostics
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
index bb7f7ac..370f732 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
@@ -35,7 +35,7 @@
   constexpr R F() const { return 0; }
 };
 constexpr int d = ConstexprMember<int>().F(); // ok
-constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}}
+constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonLiteral' cannot be used in a constant expression}}
 
 template<typename ...P> struct ConstexprCtor {
   constexpr ConstexprCtor(P...) {}
diff --git a/test/CXX/drs/dr10xx.cpp b/test/CXX/drs/dr10xx.cpp
new file mode 100644
index 0000000..64c71b2
--- /dev/null
+++ b/test/CXX/drs/dr10xx.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+// expected-no-diagnostics
+
+namespace std {
+  __extension__ typedef __SIZE_TYPE__ size_t;
+
+  template<typename T> struct initializer_list {
+    const T *p; size_t n;
+    initializer_list(const T *p, size_t n);
+  };
+}
+
+namespace dr1070 { // dr1070: 3.5
+#if __cplusplus >= 201103L
+  struct A {
+    A(std::initializer_list<int>);
+  };
+  struct B {
+    int i;
+    A a;
+  };
+  B b = {1};
+  struct C {
+    std::initializer_list<int> a;
+    B b;
+    std::initializer_list<double> c;
+  };
+  C c = {};
+#endif
+}
diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp
index 09b2869..0c0d451 100644
--- a/test/CXX/drs/dr5xx.cpp
+++ b/test/CXX/drs/dr5xx.cpp
@@ -194,3 +194,19 @@
     }
   }
 }
+
+// PR8130
+namespace dr532 { // dr532: 3.5
+  struct A { };
+
+  template<class T> struct B {
+    template<class R> int &operator*(R&);
+  };
+
+  template<class T, class R> float &operator*(T&, R&);
+  void test() {
+    A a;
+    B<A> b;
+    int &ir = b * a;
+  }
+}
diff --git a/test/CXX/drs/dr9xx.cpp b/test/CXX/drs/dr9xx.cpp
new file mode 100644
index 0000000..40dc282
--- /dev/null
+++ b/test/CXX/drs/dr9xx.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus < 201103L
+// expected-no-diagnostics
+#endif
+
+namespace std {
+  __extension__ typedef __SIZE_TYPE__ size_t;
+
+  template<typename T> struct initializer_list {
+    const T *p; size_t n;
+    initializer_list(const T *p, size_t n);
+  };
+}
+
+namespace dr990 { // dr990: 3.5
+#if __cplusplus >= 201103L
+  struct A { // expected-note 2{{candidate}}
+    A(std::initializer_list<int>); // expected-note {{candidate}}
+  };
+  struct B {
+    A a;
+  };
+  B b1 { };
+  B b2 { 1 }; // expected-error {{no viable conversion from 'int' to 'dr990::A'}}
+  B b3 { { 1 } };
+
+  struct C {
+    C();
+    C(int);
+    C(std::initializer_list<int>) = delete; // expected-note {{here}}
+  };
+  C c1[3] { 1 }; // ok
+  C c2[3] { 1, {2} }; // expected-error {{call to deleted}}
+
+  struct D {
+    D();
+    D(std::initializer_list<int>);
+    D(std::initializer_list<double>);
+  };
+  D d{};
+#endif
+}
diff --git a/test/CXX/except/except.spec/p14-ir.cpp b/test/CXX/except/except.spec/p14-ir.cpp
index 9b41f3d..68c44b5 100644
--- a/test/CXX/except/except.spec/p14-ir.cpp
+++ b/test/CXX/except/except.spec/p14-ir.cpp
@@ -26,12 +26,12 @@
 struct X5 : X0, X4 { };
 
 void test(X2 x2, X3 x3, X5 x5) {
-  // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2*) unnamed_addr
+  // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2* nonnull) unnamed_addr
   // CHECK:      call void @_ZN2X2C2ERKS_({{.*}}) [[NUW:#[0-9]+]]
   // CHECK-NEXT: ret void
   // CHECK-NEXT: }
   X2 x2a(x2);
-  // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3*) unnamed_addr
+  // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3* nonnull) unnamed_addr
   // CHECK:      call void @_ZN2X3C2ERKS_({{.*}}) [[NUW]]
   // CHECK-NEXT: ret void
   // CHECK-NEXT: }
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
deleted file mode 100644
index 60c60cb..0000000
--- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// expected-no-diagnostics
-
-// Core DR 532.
-namespace PR8130 {
-  struct A { };
-
-  template<class T> struct B {
-    template<class R> int &operator*(R&);
-  };
-
-  template<class T, class R> float &operator*(T&, R&);
-  void test() {
-    A a;
-    B<A> b;
-    int &ir = b * a;
-  }
-}
-
-namespace OperatorWithRefQualifier {
-  struct A { };
-  template<class T> struct B {
-    template<class R> int &operator*(R&) &&;
-  };
-
-  template<class T, class R> float &operator*(T&&, R&);
-  void test() {
-    A a;
-    B<A> b;
-    float &ir = b * a;
-    int &ir2 = B<A>() * a;
-  }
-}
-
-namespace OrderWithStaticMember {
-  struct A {
-    template<class T> int g(T**, int=0) { return 0; }
-    template<class T> static int g(T*) { return 1; }
-  };
-  void f() {
-    A a;
-    int **p;
-    a.g(p);
-  }
-}
-
-namespace PR17075 {
-  template <typename T> struct V {};
-  struct S { template<typename T> S &operator>>(T &t) = delete; };
-  template<typename T> S &operator>>(S &s, V<T> &v);
-  void f(S s, V<int> v) { s >> v; }
-}
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
index 8212a12..db3952a 100644
--- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
@@ -1,21 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 // expected-no-diagnostics
 
-namespace DeduceVsMember {
-  template<typename T>
-  struct X {
-    template<typename U>
-    int &operator==(const U& other) const;
-  };
-
-  template<typename T, typename U>
-  float &operator==(const T&, const X<U>&);
-
-  void test(X<int> xi, X<float> xf) {
-    float& ir = (xi == xf);
-  }
-}
-
 namespace OrderWithStaticMember {
   struct A {
     template<class T> int g(T**, int=0) { return 0; }
@@ -27,3 +13,27 @@
     a.g(p);
   }
 }
+
+#if __cplusplus >= 201103L
+namespace OperatorWithRefQualifier {
+  struct A { };
+  template<class T> struct B {
+    template<class R> int &operator*(R&) &&;
+  };
+
+  template<class T, class R> float &operator*(T&&, R&);
+  void test() {
+    A a;
+    B<A> b;
+    float &ir = b * a;
+    int &ir2 = B<A>() * a;
+  }
+}
+
+namespace PR17075 {
+  template <typename T> struct V {};
+  struct S { template<typename T> S &operator>>(T &t) = delete; };
+  template<typename T> S &operator>>(S &s, V<T> &v);
+  void f(S s, V<int> v) { s >> v; }
+}
+#endif
diff --git a/test/CXX/temp/temp.param/p14.cpp b/test/CXX/temp/temp.param/p14.cpp
deleted file mode 100644
index a6c53c1..0000000
--- a/test/CXX/temp/temp.param/p14.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s 
-// XFAIL: *
-
-// A template-parameter shall not be used in its own default argument.
-template<typename T = typename T::type> struct X; // expected-error{{default}}
diff --git a/test/CodeGen/Atomics.c b/test/CodeGen/Atomics.c
index 5798dff..684f36d 100644
--- a/test/CodeGen/Atomics.c
+++ b/test/CodeGen/Atomics.c
@@ -160,23 +160,70 @@
 
 void test_compare_and_swap (void)
 {
-  sc = __sync_val_compare_and_swap (&sc, uc, sc); // CHECK: cmpxchg i8
-  uc = __sync_val_compare_and_swap (&uc, uc, sc); // CHECK: cmpxchg i8
-  ss = __sync_val_compare_and_swap (&ss, uc, sc); // CHECK: cmpxchg i16
-  us = __sync_val_compare_and_swap (&us, uc, sc); // CHECK: cmpxchg i16
-  si = __sync_val_compare_and_swap (&si, uc, sc); // CHECK: cmpxchg i32
-  ui = __sync_val_compare_and_swap (&ui, uc, sc); // CHECK: cmpxchg i32
-  sll = __sync_val_compare_and_swap (&sll, uc, sc); // CHECK: cmpxchg i64
-  ull = __sync_val_compare_and_swap (&ull, uc, sc); // CHECK: cmpxchg i64
+  sc = __sync_val_compare_and_swap (&sc, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
+  // CHECK: extractvalue { i8, i1 } [[PAIR]], 0
 
-  ui = __sync_bool_compare_and_swap (&sc, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&uc, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&ss, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&us, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&si, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&ui, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&sll, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&ull, uc, sc); // CHECK: cmpxchg
+  uc = __sync_val_compare_and_swap (&uc, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
+  // CHECK: extractvalue { i8, i1 } [[PAIR]], 0
+
+  ss = __sync_val_compare_and_swap (&ss, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16
+  // CHECK: extractvalue { i16, i1 } [[PAIR]], 0
+
+  us = __sync_val_compare_and_swap (&us, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16
+  // CHECK: extractvalue { i16, i1 } [[PAIR]], 0
+
+  si = __sync_val_compare_and_swap (&si, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
+
+  ui = __sync_val_compare_and_swap (&ui, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
+
+  sll = __sync_val_compare_and_swap (&sll, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64
+  // CHECK: extractvalue { i64, i1 } [[PAIR]], 0
+
+  ull = __sync_val_compare_and_swap (&ull, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64
+  // CHECK: extractvalue { i64, i1 } [[PAIR]], 0
+
+
+  ui = __sync_bool_compare_and_swap (&sc, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
+  // CHECK: extractvalue { i8, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&uc, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
+  // CHECK: extractvalue { i8, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&ss, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16
+  // CHECK: extractvalue { i16, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&us, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16
+  // CHECK: extractvalue { i16, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&si, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&ui, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&sll, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64
+  // CHECK: extractvalue { i64, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&ull, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64
+  // CHECK: extractvalue { i64, i1 } [[PAIR]], 1
 }
 
 void test_lock (void)
diff --git a/test/CodeGen/aarch64-neon-2velem.c b/test/CodeGen/aarch64-neon-2velem.c
index d292b85..fa910ff 100644
--- a/test/CodeGen/aarch64-neon-2velem.c
+++ b/test/CodeGen/aarch64-neon-2velem.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
diff --git a/test/CodeGen/aarch64-neon-3v.c b/test/CodeGen/aarch64-neon-3v.c
index 866f8f5..ca32652 100644
--- a/test/CodeGen/aarch64-neon-3v.c
+++ b/test/CodeGen/aarch64-neon-3v.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
diff --git a/test/CodeGen/aarch64-neon-across.c b/test/CodeGen/aarch64-neon-across.c
index 986574a..00eb2e4 100644
--- a/test/CodeGen/aarch64-neon-across.c
+++ b/test/CodeGen/aarch64-neon-across.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-extract.c b/test/CodeGen/aarch64-neon-extract.c
index 341fb9e..cc654cc 100644
--- a/test/CodeGen/aarch64-neon-extract.c
+++ b/test/CodeGen/aarch64-neon-extract.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-fcvt-intrinsics.c b/test/CodeGen/aarch64-neon-fcvt-intrinsics.c
index b4dfe14..d1b9996 100644
--- a/test/CodeGen/aarch64-neon-fcvt-intrinsics.c
+++ b/test/CodeGen/aarch64-neon-fcvt-intrinsics.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-fma.c b/test/CodeGen/aarch64-neon-fma.c
index 753edfa..ac80833 100644
--- a/test/CodeGen/aarch64-neon-fma.c
+++ b/test/CodeGen/aarch64-neon-fma.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
diff --git a/test/CodeGen/aarch64-neon-intrinsics.c b/test/CodeGen/aarch64-neon-intrinsics.c
index 5c5209c..b120779 100644
--- a/test/CodeGen/aarch64-neon-intrinsics.c
+++ b/test/CodeGen/aarch64-neon-intrinsics.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM64
 
diff --git a/test/CodeGen/aarch64-neon-ldst-one.c b/test/CodeGen/aarch64-neon-ldst-one.c
index e163fe9..dc888c2 100644
--- a/test/CodeGen/aarch64-neon-ldst-one.c
+++ b/test/CodeGen/aarch64-neon-ldst-one.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-misc.c b/test/CodeGen/aarch64-neon-misc.c
index bab98ea..a251197 100644
--- a/test/CodeGen/aarch64-neon-misc.c
+++ b/test/CodeGen/aarch64-neon-misc.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-perm.c b/test/CodeGen/aarch64-neon-perm.c
index 1a42470..07edc11 100644
--- a/test/CodeGen/aarch64-neon-perm.c
+++ b/test/CodeGen/aarch64-neon-perm.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-scalar-copy.c b/test/CodeGen/aarch64-neon-scalar-copy.c
index e43a66e..a50a0b9 100644
--- a/test/CodeGen/aarch64-neon-scalar-copy.c
+++ b/test/CodeGen/aarch64-neon-scalar-copy.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c b/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
index 3bba353..4c2f4d7 100644
--- a/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
+++ b/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-cpu cyclone \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-shifts.c b/test/CodeGen/aarch64-neon-shifts.c
index c0b7e17..02d8ca1 100644
--- a/test/CodeGen/aarch64-neon-shifts.c
+++ b/test/CodeGen/aarch64-neon-shifts.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -emit-llvm -O1 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-tbl.c b/test/CodeGen/aarch64-neon-tbl.c
index ed542f6..902fc45 100644
--- a/test/CodeGen/aarch64-neon-tbl.c
+++ b/test/CodeGen/aarch64-neon-tbl.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/aarch64-neon-vcombine.c b/test/CodeGen/aarch64-neon-vcombine.c
index 3989f6b..a750b8e 100644
--- a/test/CodeGen/aarch64-neon-vcombine.c
+++ b/test/CodeGen/aarch64-neon-vcombine.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
diff --git a/test/CodeGen/aarch64-neon-vget-hilo.c b/test/CodeGen/aarch64-neon-vget-hilo.c
index 6b11d20..0959d09 100644
--- a/test/CodeGen/aarch64-neon-vget-hilo.c
+++ b/test/CodeGen/aarch64-neon-vget-hilo.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s --check-prefix CHECK-COMMON --check-prefix CHECK-ARM64
 
diff --git a/test/CodeGen/aarch64-poly128.c b/test/CodeGen/aarch64-poly128.c
index 85b8a84..eebecf7 100644
--- a/test/CodeGen/aarch64-poly128.c
+++ b/test/CodeGen/aarch64-poly128.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:  -ffp-contract=fast -S -O3 -o - %s | FileCheck %s --check-prefix=CHECK \
 // RUN:  --check-prefix=CHECK-ARM64
diff --git a/test/CodeGen/aarch64-poly64.c b/test/CodeGen/aarch64-poly64.c
index 8cfa0bc..290cc69 100644
--- a/test/CodeGen/aarch64-poly64.c
+++ b/test/CodeGen/aarch64-poly64.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:  -ffp-contract=fast -S -O3 -o - %s | FileCheck %s --check-prefix=CHECK \
 // RUN:  --check-prefix=CHECK-ARM64
diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c
index 5aafd95..98449d3 100644
--- a/test/CodeGen/alias.c
+++ b/test/CodeGen/alias.c
@@ -14,8 +14,8 @@
 extern void f1(void);
 extern void f1(void) __attribute((alias("f0")));
 // CHECKBASIC-DAG: @f1 = alias void ()* @f0
-// CHECKBASIC-DAG: @test8_foo = alias weak void (...), void ()* @test8_bar
-// CHECKBASIC-DAG: @test8_zed = alias void (...), void ()* @test8_bar
+// CHECKBASIC-DAG: @test8_foo = alias weak bitcast (void ()* @test8_bar to void (...)*)
+// CHECKBASIC-DAG: @test8_zed = alias bitcast (void ()* @test8_bar to void (...)*)
 // CHECKBASIC-DAG: @test9_zed = alias void ()* @test9_bar
 // CHECKBASIC: define void @f0() [[NUW:#[0-9]+]] {
 
diff --git a/test/CodeGen/altivec.c b/test/CodeGen/altivec.c
index c25d9f4..2982303 100644
--- a/test/CodeGen/altivec.c
+++ b/test/CodeGen/altivec.c
@@ -1,4 +1,3 @@
-// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
 
 // Check initialization
diff --git a/test/CodeGen/arm-aapcs-vfp.c b/test/CodeGen/arm-aapcs-vfp.c
index 96fd625..7bc1b1e 100644
--- a/test/CodeGen/arm-aapcs-vfp.c
+++ b/test/CodeGen/arm-aapcs-vfp.c
@@ -139,3 +139,9 @@
 typedef struct { int x; long long y; } struct_int_long_long;
 // CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_4(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, [3 x i32], { [2 x i64] } %k.coerce)
 void test_vfp_stack_gpr_split_4(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, struct_int_long_long k) {}
+
+// This very large struct (passed byval) uses up the GPRs, so no padding is needed
+typedef struct { int x[17]; } struct_seventeen_ints;
+typedef struct { int x[4]; } struct_four_ints;
+// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_5(%struct.struct_seventeen_ints* byval align 4 %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, double %j, { [4 x i32] } %k.coerce)
+void test_vfp_stack_gpr_split_5(struct_seventeen_ints a, double b, double c, double d, double e, double f, double g, double h, double i, double j, struct_four_ints k) {}
diff --git a/test/CodeGen/arm-asm-deprecated.c b/test/CodeGen/arm-asm-deprecated.c
new file mode 100644
index 0000000..1d7399a
--- /dev/null
+++ b/test/CodeGen/arm-asm-deprecated.c
@@ -0,0 +1,13 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple armv8 -target-feature +neon %s -S -o /dev/null -verify -DWARN
+// RUN: %clang_cc1 -triple armv8 -target-feature +neon %s -S -o /dev/null -Werror -verify
+
+void set_endian() {
+  asm("setend be");
+// expected-note@1 {{instantiated into assembly here}}
+#ifdef WARN
+// expected-warning@-3 {{deprecated}}
+#else
+// expected-error@-5 {{deprecated}}
+#endif
+}
diff --git a/test/CodeGen/arm-atomics-m.c b/test/CodeGen/arm-atomics-m.c
new file mode 100644
index 0000000..51e2d1d
--- /dev/null
+++ b/test/CodeGen/arm-atomics-m.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7m-none--eabi -target-cpu cortex-m3 | FileCheck %s
+
+int i;
+long long l;
+
+typedef enum memory_order {
+  memory_order_relaxed, memory_order_consume, memory_order_acquire,
+  memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+void test_presence(void)
+{
+  // CHECK-LABEL: @test_presence
+  // CHECK: atomicrmw add i32* {{.*}} seq_cst
+  __atomic_fetch_add(&i, 1, memory_order_seq_cst);
+  // CHECK: atomicrmw sub i32* {{.*}} seq_cst
+  __atomic_fetch_sub(&i, 1, memory_order_seq_cst);
+  // CHECK: load atomic i32* {{.*}} seq_cst
+  int r;
+  __atomic_load(&i, &r, memory_order_seq_cst);
+  // CHECK: store atomic i32 {{.*}} seq_cst
+  r = 0;
+  __atomic_store(&i, &r, memory_order_seq_cst);
+
+  // CHECK: __atomic_fetch_add_8
+  __atomic_fetch_add(&l, 1, memory_order_seq_cst);
+  // CHECK: __atomic_fetch_sub_8
+  __atomic_fetch_sub(&l, 1, memory_order_seq_cst);
+  // CHECK: __atomic_load_8
+  long long rl;
+  __atomic_load(&l, &rl, memory_order_seq_cst);
+  // CHECK: __atomic_store_8
+  rl = 0;
+  __atomic_store(&l, &rl, memory_order_seq_cst);
+}
diff --git a/test/CodeGen/arm-atomics-m0.c b/test/CodeGen/arm-atomics-m0.c
new file mode 100644
index 0000000..335a1d2
--- /dev/null
+++ b/test/CodeGen/arm-atomics-m0.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv6m-none--eabi -target-cpu cortex-m0 | FileCheck %s
+
+int i;
+long long l;
+
+typedef enum memory_order {
+  memory_order_relaxed, memory_order_consume, memory_order_acquire,
+  memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+void test_presence(void)
+{
+  // CHECK-LABEL: @test_presence
+  // CHECK: __atomic_fetch_add_4
+  __atomic_fetch_add(&i, 1, memory_order_seq_cst);
+  // CHECK: __atomic_fetch_sub_4
+  __atomic_fetch_sub(&i, 1, memory_order_seq_cst);
+  // CHECK: __atomic_load_4
+  int r;
+  __atomic_load(&i, &r, memory_order_seq_cst);
+  // CHECK: __atomic_store_4
+  r = 0;
+  __atomic_store(&i, &r, memory_order_seq_cst);
+
+  // CHECK: __atomic_fetch_add_8
+  __atomic_fetch_add(&l, 1, memory_order_seq_cst);
+  // CHECK: __atomic_fetch_sub_8
+  __atomic_fetch_sub(&l, 1, memory_order_seq_cst);
+  // CHECK: __atomic_load_8
+  long long rl;
+  __atomic_load(&l, &rl, memory_order_seq_cst);
+  // CHECK: __atomic_store_8
+  rl = 0;
+  __atomic_store(&l, &rl, memory_order_seq_cst);
+}
diff --git a/test/CodeGen/arm-atomics.c b/test/CodeGen/arm-atomics.c
new file mode 100644
index 0000000..b54e277
--- /dev/null
+++ b/test/CodeGen/arm-atomics.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-none--eabi | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv6-none--eabi | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-openbsd | FileCheck %s
+
+int i;
+long long l;
+
+typedef enum memory_order {
+  memory_order_relaxed, memory_order_consume, memory_order_acquire,
+  memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+void test_presence(void)
+{
+  // CHECK-LABEL: @test_presence
+  // CHECK: atomicrmw add i32* {{.*}} seq_cst
+  __atomic_fetch_add(&i, 1, memory_order_seq_cst);
+  // CHECK: atomicrmw sub i32* {{.*}} seq_cst
+  __atomic_fetch_sub(&i, 1, memory_order_seq_cst);
+  // CHECK: load atomic i32* {{.*}} seq_cst
+  int r;
+  __atomic_load(&i, &r, memory_order_seq_cst);
+  // CHECK: store atomic i32 {{.*}} seq_cst
+  r = 0;
+  __atomic_store(&i, &r, memory_order_seq_cst);
+
+  // CHECK: atomicrmw add i64* {{.*}} seq_cst
+  __atomic_fetch_add(&l, 1, memory_order_seq_cst);
+  // CHECK: atomicrmw sub i64* {{.*}} seq_cst
+  __atomic_fetch_sub(&l, 1, memory_order_seq_cst);
+  // CHECK: load atomic i64* {{.*}} seq_cst
+  long long rl;
+  __atomic_load(&l, &rl, memory_order_seq_cst);
+  // CHECK: store atomic i64 {{.*}} seq_cst
+  rl = 0;
+  __atomic_store(&l, &rl, memory_order_seq_cst);
+}
diff --git a/test/CodeGen/arm-be-result-return.c b/test/CodeGen/arm-be-result-return.c
new file mode 100644
index 0000000..aadc4e1
--- /dev/null
+++ b/test/CodeGen/arm-be-result-return.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple armebv7-arm-none-eabi -emit-llvm -w -o - %s | FileCheck %s
+
+// this tests for AAPCS section 5.4:
+// A Composite Type not larger than 4 bytes is returned in r0.
+// The format is as if the result had been stored in memory at a
+// word-aligned address and then loaded into r0 with an LDR instruction
+
+extern union Us { short s; } us;
+union Us callee_us() { return us; }
+// CHECK-LABEL: callee_us()
+// CHECK: zext i16
+// CHECK: shl 
+// CHECK: ret i32
+
+void caller_us() {
+  us = callee_us();
+// CHECK-LABEL: caller_us()
+// CHECK: call i32
+// CHECK: lshr i32
+// CHECK: trunc i32
+}
+
+extern struct Ss { short s; } ss;
+struct Ss callee_ss() { return ss; }
+// CHECK-LABEL: callee_ss()
+// CHECK: zext i16
+// CHECK: shl 
+// CHECK: ret i32
+
+void caller_ss() {
+  ss = callee_ss();
+// CHECK-LABEL: caller_ss()
+// CHECK: call i32
+// CHECK: lshr i32
+// CHECK: trunc i32
+}
+
diff --git a/test/CodeGen/arm-metadata.c b/test/CodeGen/arm-metadata.c
new file mode 100644
index 0000000..1cd9880
--- /dev/null
+++ b/test/CodeGen/arm-metadata.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s | FileCheck -check-prefix=DEFAULT %s
+// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fshort-enums | FileCheck -check-prefix=SHORT-ENUM %s
+// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fshort-wchar | FileCheck -check-prefix=SHORT-WCHAR %s
+
+// DEFAULT:  !{{[0-9]+}} = metadata !{i32 1, metadata !"wchar_size", i32 4}
+// DEFAULT:   !{{[0-9]+}} = metadata !{i32 1, metadata !"min_enum_size", i32 4}
+
+// SHORT-WCHAR: !{{[0-9]+}} = metadata !{i32 1, metadata !"wchar_size", i32 2}
+// SHORT-WCHAR:   !{{[0-9]+}} = metadata !{i32 1, metadata !"min_enum_size", i32 4}
+
+// SHORT_ENUM:  !{{[0-9]+}} = metadata !{i32 1, metadata !"wchar_size", i32 4}
+// SHORT-ENUM:  !{{[0-9]+}} = metadata !{i32 1, metadata !"min_enum_size", i32 1}
diff --git a/test/CodeGen/arm-microsoft-intrinsics.c b/test/CodeGen/arm-microsoft-intrinsics.c
new file mode 100644
index 0000000..5f19e5e
--- /dev/null
+++ b/test/CodeGen/arm-microsoft-intrinsics.c
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -emit-llvm -o - %s \
+// RUN:    | FileCheck %s -check-prefix CHECK-MSVC
+
+// RUN: not %clang_cc1 -triple armv7-eabi -Werror -S -o /dev/null %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EABI
+
+void check__dmb(void) {
+  __dmb(0);
+}
+
+// CHECK-MSVC: @llvm.arm.dmb(i32 0)
+// CHECK-EABI: error: implicit declaration of function '__dmb'
+
+void check__dsb(void) {
+  __dsb(0);
+}
+
+// CHECK-MSVC: @llvm.arm.dsb(i32 0)
+// CHECK-EABI: error: implicit declaration of function '__dsb'
+
+void check__isb(void) {
+  __isb(0);
+}
+
+// CHECK-MSVC: @llvm.arm.isb(i32 0)
+// CHECK-EABI: error: implicit declaration of function '__isb'
+
+__INT64_TYPE__ check__ldrexd(void) {
+  __INT64_TYPE__ i64;
+  return __ldrexd(&i64);
+}
+
+// CHECK-MSVC: @llvm.arm.ldrexd(i8* {{.*}})
+// CHECK-EABI: error: implicit declaration of function '__ldrexd'
+
+unsigned int check_MoveFromCoprocessor(void) {
+  return _MoveFromCoprocessor(0, 0, 0, 0, 0);
+}
+
+// CHECK-MSVC: @llvm.arm.mrc(i32 0, i32 0, i32 0, i32 0, i32 0)
+// CHECK-EABI: error: implicit declaration of function '_MoveFromCoprocessor'
+
+unsigned int check_MoveFromCoprocessor2(void) {
+  return _MoveFromCoprocessor2(0, 0, 0, 0, 0);
+}
+
+// CHECK-MSVC: @llvm.arm.mrc2(i32 0, i32 0, i32 0, i32 0, i32 0)
+// CHECK-EABI: error: implicit declaration of function '_MoveFromCoprocessor2'
+
+void check_MoveToCoprocessor(void) {
+  _MoveToCoprocessor(0, 0, 0, 0, 0, 0);
+}
+
+// CHECK-MSVC: @llvm.arm.mcr(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
+// CHECK-EABI: error: implicit declaration of function '_MoveToCoprocessor'
+
+void check_MoveToCoprocessor2(void) {
+  _MoveToCoprocessor2(0, 0, 0, 0, 0, 0);
+}
+
+// CHECK-MSVC: @llvm.arm.mcr2(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
+// CHECK-EABI: error: implicit declaration of function '_MoveToCoprocessor2'
+
diff --git a/test/CodeGen/arm64-crc32.c b/test/CodeGen/arm64-crc32.c
index a1c447a..37ced18 100644
--- a/test/CodeGen/arm64-crc32.c
+++ b/test/CodeGen/arm64-crc32.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu \
 // RUN:   -O3 -S -emit-llvm -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/arm64-lanes.c b/test/CodeGen/arm64-lanes.c
index b0d4694..8ab2bd4 100644
--- a/test/CodeGen/arm64-lanes.c
+++ b/test/CodeGen/arm64-lanes.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O3 -triple arm64_be-linux-gnu -target-feature +neon -ffreestanding -emit-llvm -o - %s | FileCheck %s --check-prefix CHECK-BE
 
 #include <arm_neon.h>
 
@@ -6,58 +7,68 @@
 int8_t test_vdupb_lane_s8(int8x8_t src) {
   return vdupb_lane_s8(src, 2);
   // CHECK: extractelement <8 x i8> %src, i32 2
+  // CHECK-BE: extractelement <8 x i8> %src, i32 5
 }
 
 // CHECK-LABEL: @test_vdupb_lane_u8
 uint8_t test_vdupb_lane_u8(uint8x8_t src) {
   return vdupb_lane_u8(src, 2);
   // CHECK: extractelement <8 x i8> %src, i32 2
+  // CHECK-BE: extractelement <8 x i8> %src, i32 5
 }
 
 // CHECK-LABEL: @test_vduph_lane_s16
 int16_t test_vduph_lane_s16(int16x4_t src) {
   return vduph_lane_s16(src, 2);
   // CHECK: extractelement <4 x i16> %src, i32 2
+  // CHECK-BE: extractelement <4 x i16> %src, i32 1
 }
 
 // CHECK-LABEL: @test_vduph_lane_u16
 uint16_t test_vduph_lane_u16(uint16x4_t src) {
   return vduph_lane_u16(src, 2);
   // CHECK: extractelement <4 x i16> %src, i32 2
+  // CHECK-BE: extractelement <4 x i16> %src, i32 1
 }
 
 // CHECK-LABEL: @test_vdups_lane_s32
 int32_t test_vdups_lane_s32(int32x2_t src) {
   return vdups_lane_s32(src, 0);
   // CHECK: extractelement <2 x i32> %src, i32 0
+  // CHECK-BE: extractelement <2 x i32> %src, i32 1
 }
 
 // CHECK-LABEL: @test_vdups_lane_u32
 uint32_t test_vdups_lane_u32(uint32x2_t src) {
   return vdups_lane_u32(src, 0);
   // CHECK: extractelement <2 x i32> %src, i32 0
+  // CHECK-BE: extractelement <2 x i32> %src, i32 1
 }
 
 // CHECK-LABEL: @test_vdups_lane_f32
 float32_t test_vdups_lane_f32(float32x2_t src) {
   return vdups_lane_f32(src, 0);
   // CHECK: extractelement <2 x float> %src, i32 0
+  // CHECK-BE: extractelement <2 x float> %src, i32 1
 }
 
 // CHECK-LABEL: @test_vdupd_lane_s64
 int64_t test_vdupd_lane_s64(int64x1_t src) {
   return vdupd_lane_s64(src, 0);
   // CHECK: extractelement <1 x i64> %src, i32 0
+  // CHECK-BE: extractelement <1 x i64> %src, i32 0
 }
 
 // CHECK-LABEL: @test_vdupd_lane_u64
 uint64_t test_vdupd_lane_u64(uint64x1_t src) {
   return vdupd_lane_u64(src, 0);
   // CHECK: extractelement <1 x i64> %src, i32 0
+  // CHECK-BE: extractelement <1 x i64> %src, i32 0
 }
 
 // CHECK-LABEL: @test_vdupd_lane_f64
 float64_t test_vdupd_lane_f64(float64x1_t src) {
   return vdupd_lane_f64(src, 0);
   // CHECK: extractelement <1 x double> %src, i32 0
+  // CHECK-BE: extractelement <1 x double> %src, i32 0
 }
diff --git a/test/CodeGen/arm64-scalar-test.c b/test/CodeGen/arm64-scalar-test.c
index a956c84..e2328b1 100644
--- a/test/CodeGen/arm64-scalar-test.c
+++ b/test/CodeGen/arm64-scalar-test.c
@@ -1,4 +1,4 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon  \
 // RUN:   -S -O1 -o - -ffreestanding %s | FileCheck %s
 
diff --git a/test/CodeGen/arm64_crypto.c b/test/CodeGen/arm64_crypto.c
index c672d2d..e63009a 100644
--- a/test/CodeGen/arm64_crypto.c
+++ b/test/CodeGen/arm64_crypto.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +crypto -ffreestanding -Os -S -o - %s | FileCheck %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 
 #include <arm_neon.h>
 
diff --git a/test/CodeGen/arm64_neon_high_half.c b/test/CodeGen/arm64_neon_high_half.c
index 0cda5e1..577a09e 100644
--- a/test/CodeGen/arm64_neon_high_half.c
+++ b/test/CodeGen/arm64_neon_high_half.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -ffreestanding -Os -S -o - %s | FileCheck %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 
 #include <arm_neon.h>
 
diff --git a/test/CodeGen/arm64_vMaxMin.c b/test/CodeGen/arm64_vMaxMin.c
index 379033e..5f77b6c 100644
--- a/test/CodeGen/arm64_vMaxMin.c
+++ b/test/CodeGen/arm64_vMaxMin.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
 // RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | FileCheck -check-prefix=CHECK-CODEGEN %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // Test ARM64 SIMD max/min intrinsics
 
 #include <arm_neon.h>
diff --git a/test/CodeGen/arm64_vcvtfp.c b/test/CodeGen/arm64_vcvtfp.c
index 79c37ad..e3dca81 100644
--- a/test/CodeGen/arm64_vcvtfp.c
+++ b/test/CodeGen/arm64_vcvtfp.c
@@ -44,5 +44,5 @@
   return vcvtx_high_f32_f64(x, v);
   // CHECK: llvm.aarch64.neon.fcvtxn.v2f32.v2f64
   // CHECK: shufflevector
-  // CHECK-NEXT: ret
+  // CHECK: ret
 }
diff --git a/test/CodeGen/arm64_vdupq_n_f64.c b/test/CodeGen/arm64_vdupq_n_f64.c
index 73e1cc4..ffba55c 100644
--- a/test/CodeGen/arm64_vdupq_n_f64.c
+++ b/test/CodeGen/arm64_vdupq_n_f64.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | FileCheck %s
 // RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | \
 // RUN:   FileCheck -check-prefix=CHECK-IR %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 
 /// Test vdupq_n_f64 and vmovq_nf64 ARM64 intrinsics
 // <rdar://problem/11778405> ARM64: vdupq_n_f64 and vdupq_lane_f64 intrinsics
diff --git a/test/CodeGen/arm64_vecCmpBr.c b/test/CodeGen/arm64_vecCmpBr.c
index 08fa6f7..3ae7433 100644
--- a/test/CodeGen/arm64_vecCmpBr.c
+++ b/test/CodeGen/arm64_vecCmpBr.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -S -ffreestanding %s -o - -target-cpu cyclone | FileCheck %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // test code generation for <rdar://problem/11487757>
 #include <arm_neon.h>
 
diff --git a/test/CodeGen/arm64_vqmov.c b/test/CodeGen/arm64_vqmov.c
index 38acc0c..6480e66 100644
--- a/test/CodeGen/arm64_vqmov.c
+++ b/test/CodeGen/arm64_vqmov.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | FileCheck %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 /// Test vqmov[u]n_high_<su>{16,32,64) ARM64 intrinsics
 
 #include <arm_neon.h>
diff --git a/test/CodeGen/arm64_vrecps.c b/test/CodeGen/arm64_vrecps.c
index 1febaa1..a3af13c 100644
--- a/test/CodeGen/arm64_vrecps.c
+++ b/test/CodeGen/arm64_vrecps.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | FileCheck %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 /// Test vrecpss_f32, vrecpsd_f64 ARM64 intrinsics
 
 
diff --git a/test/CodeGen/arm64_vsli.c b/test/CodeGen/arm64_vsli.c
index eb74bd3..b2a30ab 100644
--- a/test/CodeGen/arm64_vsli.c
+++ b/test/CodeGen/arm64_vsli.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
 // RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | \
 // RUN:   FileCheck -check-prefix=CHECK_CODEGEN %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // Test
 
 #include <arm_neon.h>
diff --git a/test/CodeGen/arm64_vsri.c b/test/CodeGen/arm64_vsri.c
index 237e32e..579431d 100644
--- a/test/CodeGen/arm64_vsri.c
+++ b/test/CodeGen/arm64_vsri.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
 // RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | \
 // RUN:   FileCheck -check-prefix=CHECK_CODEGEN %s
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 
 // Test ARM64 SIMD vector shift right and insert: vsri[q]_n_*
 
diff --git a/test/CodeGen/arm_acle.c b/test/CodeGen/arm_acle.c
new file mode 100644
index 0000000..88d58a4
--- /dev/null
+++ b/test/CodeGen/arm_acle.c
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -ffreestanding -triple armv8 -target-cpu cortex-a57 -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32
+// RUN: %clang_cc1 -ffreestanding -triple aarch64 -target-cpu cortex-a57 -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64
+
+#include <arm_acle.h>
+
+/* Miscellaneous data-processing intrinsics */
+// ARM-LABEL: test_rev
+// ARM: call i32 @llvm.bswap.i32(i32 %t)
+uint32_t test_rev(uint32_t t) {
+  return __rev(t);
+}
+
+// ARM-LABEL: test_revl
+// AArch32: call i32 @llvm.bswap.i32(i32 %t)
+// AArch64: call i64 @llvm.bswap.i64(i64 %t)
+long test_revl(long t) {
+  return __revl(t);
+}
+
+// ARM-LABEL: test_revll
+// ARM: call i64 @llvm.bswap.i64(i64 %t)
+uint64_t test_revll(uint64_t t) {
+  return __revll(t);
+}
+
+// ARM-LABEL: test_clz
+// ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
+uint32_t test_clz(uint32_t t) {
+  return __clz(t);
+}
+
+// ARM-LABEL: test_clzl
+// AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
+// AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
+long test_clzl(long t) {
+  return __clzl(t);
+}
+
+// ARM-LABEL: test_clzll
+// ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
+uint64_t test_clzll(uint64_t t) {
+  return __clzll(t);
+}
+
+/* Saturating intrinsics */
+#ifdef __ARM_32BIT_STATE
+// AArch32-LABEL: test_ssat
+// AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1)
+int32_t test_ssat(int32_t t) {
+  return __ssat(t, 1);
+}
+
+// AArch32-LABEL: test_usat
+// AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2)
+int32_t test_usat(int32_t t) {
+  return __usat(t, 2);
+}
+// AArch32-LABEL: test_qadd
+// AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b)
+int32_t test_qadd(int32_t a, int32_t b) {
+  return __qadd(a, b);
+}
+
+// AArch32-LABEL: test_qsub
+// AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b)
+int32_t test_qsub(int32_t a, int32_t b) {
+  return __qsub(a, b);
+}
+
+extern int32_t f();
+// AArch32-LABEL: test_qdbl
+// AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f
+// AArch32-NOT: call {{.*}} @f
+// AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]])
+int32_t test_qdbl() {
+  return __qdbl(f());
+}
+#endif
+
+/* CRC32 intrinsics */
+// ARM-LABEL: test_crc32b
+// AArch32: call i32 @llvm.arm.crc32b
+// AArch64: call i32 @llvm.aarch64.crc32b
+uint32_t test_crc32b(uint32_t a, uint8_t b) {
+  return __crc32b(a, b);
+}
+
+// ARM-LABEL: test_crc32h
+// AArch32: call i32 @llvm.arm.crc32h
+// AArch64: call i32 @llvm.aarch64.crc32h
+uint32_t test_crc32h(uint32_t a, uint16_t b) {
+  return __crc32h(a, b);
+}
+
+// ARM-LABEL: test_crc32w
+// AArch32: call i32 @llvm.arm.crc32w
+// AArch64: call i32 @llvm.aarch64.crc32w
+uint32_t test_crc32w(uint32_t a, uint32_t b) {
+  return __crc32w(a, b);
+}
+
+// ARM-LABEL: test_crc32d
+// AArch32: call i32 @llvm.arm.crc32w
+// AArch32: call i32 @llvm.arm.crc32w
+// AArch64: call i32 @llvm.aarch64.crc32x
+uint32_t test_crc32d(uint32_t a, uint64_t b) {
+  return __crc32d(a, b);
+}
+
+// ARM-LABEL: test_crc32cb
+// AArch32: call i32 @llvm.arm.crc32cb
+// AArch64: call i32 @llvm.aarch64.crc32cb
+uint32_t test_crc32cb(uint32_t a, uint8_t b) {
+  return __crc32cb(a, b);
+}
+
+// ARM-LABEL: test_crc32ch
+// AArch32: call i32 @llvm.arm.crc32ch
+// AArch64: call i32 @llvm.aarch64.crc32ch
+uint32_t test_crc32ch(uint32_t a, uint16_t b) {
+  return __crc32ch(a, b);
+}
+
+// ARM-LABEL: test_crc32cw
+// AArch32: call i32 @llvm.arm.crc32cw
+// AArch64: call i32 @llvm.aarch64.crc32cw
+uint32_t test_crc32cw(uint32_t a, uint32_t b) {
+  return __crc32cw(a, b);
+}
+
+// ARM-LABEL: test_crc32cd
+// AArch32: call i32 @llvm.arm.crc32cw
+// AArch32: call i32 @llvm.arm.crc32cw
+// AArch64: call i32 @llvm.aarch64.crc32cx
+uint32_t test_crc32cd(uint32_t a, uint64_t b) {
+  return __crc32cd(a, b);
+}
diff --git a/test/CodeGen/arm_neon_intrinsics.c b/test/CodeGen/arm_neon_intrinsics.c
index 9ec3451..a084d8b 100644
--- a/test/CodeGen/arm_neon_intrinsics.c
+++ b/test/CodeGen/arm_neon_intrinsics.c
@@ -1,11657 +1,11673 @@
 // RUN: %clang_cc1 -triple thumbv7s-apple-darwin -target-abi apcs-gnu\
 // RUN:  -target-cpu swift -ffreestanding -Os -S -o - %s\
-// RUN:  | FileCheck %s
+// RUN:  | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SWIFT
+// RUN: %clang_cc1 -triple armv8-linux-gnu \
+// RUN:  -target-cpu cortex-a57 -mfloat-abi soft -ffreestanding -Os -S -o - %s\
+// RUN:  | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-A57
 
 // REQUIRES: long_tests
 
 #include <arm_neon.h>
 
-// CHECK: test_vaba_s8
+// CHECK-LABEL: test_vaba_s8
 // CHECK: vaba.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vaba_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
   return vaba_s8(a, b, c);
 }
 
-// CHECK: test_vaba_s16
+// CHECK-LABEL: test_vaba_s16
 // CHECK: vaba.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vaba_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vaba_s16(a, b, c);
 }
 
-// CHECK: test_vaba_s32
+// CHECK-LABEL: test_vaba_s32
 // CHECK: vaba.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vaba_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vaba_s32(a, b, c);
 }
 
-// CHECK: test_vaba_u8
+// CHECK-LABEL: test_vaba_u8
 // CHECK: vaba.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vaba_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vaba_u8(a, b, c);
 }
 
-// CHECK: test_vaba_u16
+// CHECK-LABEL: test_vaba_u16
 // CHECK: vaba.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vaba_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vaba_u16(a, b, c);
 }
 
-// CHECK: test_vaba_u32
+// CHECK-LABEL: test_vaba_u32
 // CHECK: vaba.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vaba_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vaba_u32(a, b, c);
 }
 
-// CHECK: test_vabaq_s8
+// CHECK-LABEL: test_vabaq_s8
 // CHECK: vaba.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vabaq_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
   return vabaq_s8(a, b, c);
 }
 
-// CHECK: test_vabaq_s16
+// CHECK-LABEL: test_vabaq_s16
 // CHECK: vaba.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vabaq_s16(int16x8_t a, int16x8_t b, int16x8_t c) {
   return vabaq_s16(a, b, c);
 }
 
-// CHECK: test_vabaq_s32
+// CHECK-LABEL: test_vabaq_s32
 // CHECK: vaba.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vabaq_s32(int32x4_t a, int32x4_t b, int32x4_t c) {
   return vabaq_s32(a, b, c);
 }
 
-// CHECK: test_vabaq_u8
+// CHECK-LABEL: test_vabaq_u8
 // CHECK: vaba.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vabaq_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
   return vabaq_u8(a, b, c);
 }
 
-// CHECK: test_vabaq_u16
+// CHECK-LABEL: test_vabaq_u16
 // CHECK: vaba.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vabaq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t c) {
   return vabaq_u16(a, b, c);
 }
 
-// CHECK: test_vabaq_u32
+// CHECK-LABEL: test_vabaq_u32
 // CHECK: vaba.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vabaq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
   return vabaq_u32(a, b, c);
 }
 
 
-// CHECK: test_vabal_s8
+// CHECK-LABEL: test_vabal_s8
 // CHECK: vabal.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vabal_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
   return vabal_s8(a, b, c);
 }
 
-// CHECK: test_vabal_s16
+// CHECK-LABEL: test_vabal_s16
 // CHECK: vabal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vabal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vabal_s16(a, b, c);
 }
 
-// CHECK: test_vabal_s32
+// CHECK-LABEL: test_vabal_s32
 // CHECK: vabal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vabal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vabal_s32(a, b, c);
 }
 
-// CHECK: test_vabal_u8
+// CHECK-LABEL: test_vabal_u8
 // CHECK: vabal.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vabal_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
   return vabal_u8(a, b, c);
 }
 
-// CHECK: test_vabal_u16
+// CHECK-LABEL: test_vabal_u16
 // CHECK: vabal.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vabal_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vabal_u16(a, b, c);
 }
 
-// CHECK: test_vabal_u32
+// CHECK-LABEL: test_vabal_u32
 // CHECK: vabal.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vabal_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vabal_u32(a, b, c);
 }
 
 
-// CHECK: test_vabd_s8
+// CHECK-LABEL: test_vabd_s8
 // CHECK: vabd.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vabd_s8(int8x8_t a, int8x8_t b) {
   return vabd_s8(a, b);
 }
 
-// CHECK: test_vabd_s16
+// CHECK-LABEL: test_vabd_s16
 // CHECK: vabd.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vabd_s16(int16x4_t a, int16x4_t b) {
   return vabd_s16(a, b);
 }
 
-// CHECK: test_vabd_s32
+// CHECK-LABEL: test_vabd_s32
 // CHECK: vabd.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vabd_s32(int32x2_t a, int32x2_t b) {
   return vabd_s32(a, b);
 }
 
-// CHECK: test_vabd_u8
+// CHECK-LABEL: test_vabd_u8
 // CHECK: vabd.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vabd_u8(uint8x8_t a, uint8x8_t b) {
   return vabd_u8(a, b);
 }
 
-// CHECK: test_vabd_u16
+// CHECK-LABEL: test_vabd_u16
 // CHECK: vabd.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vabd_u16(uint16x4_t a, uint16x4_t b) {
   return vabd_u16(a, b);
 }
 
-// CHECK: test_vabd_u32
+// CHECK-LABEL: test_vabd_u32
 // CHECK: vabd.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vabd_u32(uint32x2_t a, uint32x2_t b) {
   return vabd_u32(a, b);
 }
 
-// CHECK: test_vabd_f32
+// CHECK-LABEL: test_vabd_f32
 // CHECK: vabd.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vabd_f32(float32x2_t a, float32x2_t b) {
   return vabd_f32(a, b);
 }
 
-// CHECK: test_vabdq_s8
+// CHECK-LABEL: test_vabdq_s8
 // CHECK: vabd.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vabdq_s8(int8x16_t a, int8x16_t b) {
   return vabdq_s8(a, b);
 }
 
-// CHECK: test_vabdq_s16
+// CHECK-LABEL: test_vabdq_s16
 // CHECK: vabd.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vabdq_s16(int16x8_t a, int16x8_t b) {
   return vabdq_s16(a, b);
 }
 
-// CHECK: test_vabdq_s32
+// CHECK-LABEL: test_vabdq_s32
 // CHECK: vabd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vabdq_s32(int32x4_t a, int32x4_t b) {
   return vabdq_s32(a, b);
 }
 
-// CHECK: test_vabdq_u8
+// CHECK-LABEL: test_vabdq_u8
 // CHECK: vabd.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vabdq_u8(uint8x16_t a, uint8x16_t b) {
   return vabdq_u8(a, b);
 }
 
-// CHECK: test_vabdq_u16
+// CHECK-LABEL: test_vabdq_u16
 // CHECK: vabd.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vabdq_u16(uint16x8_t a, uint16x8_t b) {
   return vabdq_u16(a, b);
 }
 
-// CHECK: test_vabdq_u32
+// CHECK-LABEL: test_vabdq_u32
 // CHECK: vabd.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vabdq_u32(uint32x4_t a, uint32x4_t b) {
   return vabdq_u32(a, b);
 }
 
-// CHECK: test_vabdq_f32
+// CHECK-LABEL: test_vabdq_f32
 // CHECK: vabd.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vabdq_f32(float32x4_t a, float32x4_t b) {
   return vabdq_f32(a, b);
 }
 
 
-// CHECK: test_vabdl_s8
+// CHECK-LABEL: test_vabdl_s8
 // CHECK: vabdl.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vabdl_s8(int8x8_t a, int8x8_t b) {
   return vabdl_s8(a, b);
 }
 
-// CHECK: test_vabdl_s16
+// CHECK-LABEL: test_vabdl_s16
 // CHECK: vabdl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vabdl_s16(int16x4_t a, int16x4_t b) {
   return vabdl_s16(a, b);
 }
 
-// CHECK: test_vabdl_s32
+// CHECK-LABEL: test_vabdl_s32
 // CHECK: vabdl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vabdl_s32(int32x2_t a, int32x2_t b) {
   return vabdl_s32(a, b);
 }
 
-// CHECK: test_vabdl_u8
+// CHECK-LABEL: test_vabdl_u8
 // CHECK: vabdl.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vabdl_u8(uint8x8_t a, uint8x8_t b) {
   return vabdl_u8(a, b);
 }
 
-// CHECK: test_vabdl_u16
+// CHECK-LABEL: test_vabdl_u16
 // CHECK: vabdl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vabdl_u16(uint16x4_t a, uint16x4_t b) {
   return vabdl_u16(a, b);
 }
 
-// CHECK: test_vabdl_u32
+// CHECK-LABEL: test_vabdl_u32
 // CHECK: vabdl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vabdl_u32(uint32x2_t a, uint32x2_t b) {
   return vabdl_u32(a, b);
 }
 
 
-// CHECK: test_vabs_s8
+// CHECK-LABEL: test_vabs_s8
 // CHECK: vabs.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vabs_s8(int8x8_t a) {
   return vabs_s8(a);
 }
 
-// CHECK: test_vabs_s16
+// CHECK-LABEL: test_vabs_s16
 // CHECK: vabs.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vabs_s16(int16x4_t a) {
   return vabs_s16(a);
 }
 
-// CHECK: test_vabs_s32
+// CHECK-LABEL: test_vabs_s32
 // CHECK: vabs.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vabs_s32(int32x2_t a) {
   return vabs_s32(a);
 }
 
-// CHECK: test_vabs_f32
+// CHECK-LABEL: test_vabs_f32
 // CHECK: vabs.f32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vabs_f32(float32x2_t a) {
   return vabs_f32(a);
 }
 
-// CHECK: test_vabsq_s8
+// CHECK-LABEL: test_vabsq_s8
 // CHECK: vabs.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vabsq_s8(int8x16_t a) {
   return vabsq_s8(a);
 }
 
-// CHECK: test_vabsq_s16
+// CHECK-LABEL: test_vabsq_s16
 // CHECK: vabs.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vabsq_s16(int16x8_t a) {
   return vabsq_s16(a);
 }
 
-// CHECK: test_vabsq_s32
+// CHECK-LABEL: test_vabsq_s32
 // CHECK: vabs.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vabsq_s32(int32x4_t a) {
   return vabsq_s32(a);
 }
 
-// CHECK: test_vabsq_f32
+// CHECK-LABEL: test_vabsq_f32
 // CHECK: vabs.f32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vabsq_f32(float32x4_t a) {
   return vabsq_f32(a);
 }
 
 
-// CHECK: test_vadd_s8
+// CHECK-LABEL: test_vadd_s8
 // CHECK: vadd.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vadd_s8(int8x8_t a, int8x8_t b) {
   return vadd_s8(a, b);
 }
 
-// CHECK: test_vadd_s16
+// CHECK-LABEL: test_vadd_s16
 // CHECK: vadd.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vadd_s16(int16x4_t a, int16x4_t b) {
   return vadd_s16(a, b);
 }
 
-// CHECK: test_vadd_s32
+// CHECK-LABEL: test_vadd_s32
 // CHECK: vadd.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vadd_s32(int32x2_t a, int32x2_t b) {
   return vadd_s32(a, b);
 }
 
-// CHECK: test_vadd_s64
+// CHECK-LABEL: test_vadd_s64
 // CHECK: vadd.i64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vadd_s64(int64x1_t a, int64x1_t b) {
   return vadd_s64(a, b);
 }
 
-// CHECK: test_vadd_f32
+// CHECK-LABEL: test_vadd_f32
 // CHECK: vadd.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vadd_f32(float32x2_t a, float32x2_t b) {
   return vadd_f32(a, b);
 }
 
-// CHECK: test_vadd_u8
+// CHECK-LABEL: test_vadd_u8
 // CHECK: vadd.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vadd_u8(uint8x8_t a, uint8x8_t b) {
   return vadd_u8(a, b);
 }
 
-// CHECK: test_vadd_u16
+// CHECK-LABEL: test_vadd_u16
 // CHECK: vadd.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vadd_u16(uint16x4_t a, uint16x4_t b) {
   return vadd_u16(a, b);
 }
 
-// CHECK: test_vadd_u32
+// CHECK-LABEL: test_vadd_u32
 // CHECK: vadd.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vadd_u32(uint32x2_t a, uint32x2_t b) {
   return vadd_u32(a, b);
 }
 
-// CHECK: test_vadd_u64
+// CHECK-LABEL: test_vadd_u64
 // CHECK: vadd.i64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vadd_u64(uint64x1_t a, uint64x1_t b) {
   return vadd_u64(a, b);
 }
 
-// CHECK: test_vaddq_s8
+// CHECK-LABEL: test_vaddq_s8
 // CHECK: vadd.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vaddq_s8(int8x16_t a, int8x16_t b) {
   return vaddq_s8(a, b);
 }
 
-// CHECK: test_vaddq_s16
+// CHECK-LABEL: test_vaddq_s16
 // CHECK: vadd.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vaddq_s16(int16x8_t a, int16x8_t b) {
   return vaddq_s16(a, b);
 }
 
-// CHECK: test_vaddq_s32
+// CHECK-LABEL: test_vaddq_s32
 // CHECK: vadd.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vaddq_s32(int32x4_t a, int32x4_t b) {
   return vaddq_s32(a, b);
 }
 
-// CHECK: test_vaddq_s64
+// CHECK-LABEL: test_vaddq_s64
 // CHECK: vadd.i64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vaddq_s64(int64x2_t a, int64x2_t b) {
   return vaddq_s64(a, b);
 }
 
-// CHECK: test_vaddq_f32
+// CHECK-LABEL: test_vaddq_f32
 // CHECK: vadd.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vaddq_f32(float32x4_t a, float32x4_t b) {
   return vaddq_f32(a, b);
 }
 
-// CHECK: test_vaddq_u8
+// CHECK-LABEL: test_vaddq_u8
 // CHECK: vadd.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vaddq_u8(uint8x16_t a, uint8x16_t b) {
   return vaddq_u8(a, b);
 }
 
-// CHECK: test_vaddq_u16
+// CHECK-LABEL: test_vaddq_u16
 // CHECK: vadd.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vaddq_u16(uint16x8_t a, uint16x8_t b) {
   return vaddq_u16(a, b);
 }
 
-// CHECK: test_vaddq_u32
+// CHECK-LABEL: test_vaddq_u32
 // CHECK: vadd.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vaddq_u32(uint32x4_t a, uint32x4_t b) {
   return vaddq_u32(a, b);
 }
 
-// CHECK: test_vaddq_u64
+// CHECK-LABEL: test_vaddq_u64
 // CHECK: vadd.i64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vaddq_u64(uint64x2_t a, uint64x2_t b) {
   return vaddq_u64(a, b);
 }
 
 
-// CHECK: test_vaddhn_s16
+// CHECK-LABEL: test_vaddhn_s16
 // CHECK: vaddhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vaddhn_s16(int16x8_t a, int16x8_t b) {
   return vaddhn_s16(a, b);
 }
 
-// CHECK: test_vaddhn_s32
+// CHECK-LABEL: test_vaddhn_s32
 // CHECK: vaddhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vaddhn_s32(int32x4_t a, int32x4_t b) {
   return vaddhn_s32(a, b);
 }
 
-// CHECK: test_vaddhn_s64
+// CHECK-LABEL: test_vaddhn_s64
 // CHECK: vaddhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vaddhn_s64(int64x2_t a, int64x2_t b) {
   return vaddhn_s64(a, b);
 }
 
-// CHECK: test_vaddhn_u16
+// CHECK-LABEL: test_vaddhn_u16
 // CHECK: vaddhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vaddhn_u16(uint16x8_t a, uint16x8_t b) {
   return vaddhn_u16(a, b);
 }
 
-// CHECK: test_vaddhn_u32
+// CHECK-LABEL: test_vaddhn_u32
 // CHECK: vaddhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vaddhn_u32(uint32x4_t a, uint32x4_t b) {
   return vaddhn_u32(a, b);
 }
 
-// CHECK: test_vaddhn_u64
+// CHECK-LABEL: test_vaddhn_u64
 // CHECK: vaddhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vaddhn_u64(uint64x2_t a, uint64x2_t b) {
   return vaddhn_u64(a, b);
 }
 
 
-// CHECK: test_vaddl_s8
+// CHECK-LABEL: test_vaddl_s8
 // CHECK: vaddl.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vaddl_s8(int8x8_t a, int8x8_t b) {
   return vaddl_s8(a, b);
 }
 
-// CHECK: test_vaddl_s16
+// CHECK-LABEL: test_vaddl_s16
 // CHECK: vaddl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vaddl_s16(int16x4_t a, int16x4_t b) {
   return vaddl_s16(a, b);
 }
 
-// CHECK: test_vaddl_s32
+// CHECK-LABEL: test_vaddl_s32
 // CHECK: vaddl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vaddl_s32(int32x2_t a, int32x2_t b) {
   return vaddl_s32(a, b);
 }
 
-// CHECK: test_vaddl_u8
+// CHECK-LABEL: test_vaddl_u8
 // CHECK: vaddl.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vaddl_u8(uint8x8_t a, uint8x8_t b) {
   return vaddl_u8(a, b);
 }
 
-// CHECK: test_vaddl_u16
+// CHECK-LABEL: test_vaddl_u16
 // CHECK: vaddl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vaddl_u16(uint16x4_t a, uint16x4_t b) {
   return vaddl_u16(a, b);
 }
 
-// CHECK: test_vaddl_u32
+// CHECK-LABEL: test_vaddl_u32
 // CHECK: vaddl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vaddl_u32(uint32x2_t a, uint32x2_t b) {
   return vaddl_u32(a, b);
 }
 
 
-// CHECK: test_vaddw_s8
+// CHECK-LABEL: test_vaddw_s8
 // CHECK: vaddw.s8 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vaddw_s8(int16x8_t a, int8x8_t b) {
   return vaddw_s8(a, b);
 }
 
-// CHECK: test_vaddw_s16
+// CHECK-LABEL: test_vaddw_s16
 // CHECK: vaddw.s16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vaddw_s16(int32x4_t a, int16x4_t b) {
   return vaddw_s16(a, b);
 }
 
-// CHECK: test_vaddw_s32
+// CHECK-LABEL: test_vaddw_s32
 // CHECK: vaddw.s32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vaddw_s32(int64x2_t a, int32x2_t b) {
   return vaddw_s32(a, b);
 }
 
-// CHECK: test_vaddw_u8
+// CHECK-LABEL: test_vaddw_u8
 // CHECK: vaddw.u8 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vaddw_u8(uint16x8_t a, uint8x8_t b) {
   return vaddw_u8(a, b);
 }
 
-// CHECK: test_vaddw_u16
+// CHECK-LABEL: test_vaddw_u16
 // CHECK: vaddw.u16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vaddw_u16(uint32x4_t a, uint16x4_t b) {
   return vaddw_u16(a, b);
 }
 
-// CHECK: test_vaddw_u32
+// CHECK-LABEL: test_vaddw_u32
 // CHECK: vaddw.u32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vaddw_u32(uint64x2_t a, uint32x2_t b) {
   return vaddw_u32(a, b);
 }
 
 
-// CHECK: test_vand_s8
+// CHECK-LABEL: test_vand_s8
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vand_s8(int8x8_t a, int8x8_t b) {
   return vand_s8(a, b);
 }
 
-// CHECK: test_vand_s16
+// CHECK-LABEL: test_vand_s16
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vand_s16(int16x4_t a, int16x4_t b) {
   return vand_s16(a, b);
 }
 
-// CHECK: test_vand_s32
+// CHECK-LABEL: test_vand_s32
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vand_s32(int32x2_t a, int32x2_t b) {
   return vand_s32(a, b);
 }
 
-// CHECK: test_vand_s64
+// CHECK-LABEL: test_vand_s64
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vand_s64(int64x1_t a, int64x1_t b) {
   return vand_s64(a, b);
 }
 
-// CHECK: test_vand_u8
+// CHECK-LABEL: test_vand_u8
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vand_u8(uint8x8_t a, uint8x8_t b) {
   return vand_u8(a, b);
 }
 
-// CHECK: test_vand_u16
+// CHECK-LABEL: test_vand_u16
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vand_u16(uint16x4_t a, uint16x4_t b) {
   return vand_u16(a, b);
 }
 
-// CHECK: test_vand_u32
+// CHECK-LABEL: test_vand_u32
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vand_u32(uint32x2_t a, uint32x2_t b) {
   return vand_u32(a, b);
 }
 
-// CHECK: test_vand_u64
+// CHECK-LABEL: test_vand_u64
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vand_u64(uint64x1_t a, uint64x1_t b) {
   return vand_u64(a, b);
 }
 
-// CHECK: test_vandq_s8
+// CHECK-LABEL: test_vandq_s8
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vandq_s8(int8x16_t a, int8x16_t b) {
   return vandq_s8(a, b);
 }
 
-// CHECK: test_vandq_s16
+// CHECK-LABEL: test_vandq_s16
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vandq_s16(int16x8_t a, int16x8_t b) {
   return vandq_s16(a, b);
 }
 
-// CHECK: test_vandq_s32
+// CHECK-LABEL: test_vandq_s32
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vandq_s32(int32x4_t a, int32x4_t b) {
   return vandq_s32(a, b);
 }
 
-// CHECK: test_vandq_s64
+// CHECK-LABEL: test_vandq_s64
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vandq_s64(int64x2_t a, int64x2_t b) {
   return vandq_s64(a, b);
 }
 
-// CHECK: test_vandq_u8
+// CHECK-LABEL: test_vandq_u8
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vandq_u8(uint8x16_t a, uint8x16_t b) {
   return vandq_u8(a, b);
 }
 
-// CHECK: test_vandq_u16
+// CHECK-LABEL: test_vandq_u16
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vandq_u16(uint16x8_t a, uint16x8_t b) {
   return vandq_u16(a, b);
 }
 
-// CHECK: test_vandq_u32
+// CHECK-LABEL: test_vandq_u32
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vandq_u32(uint32x4_t a, uint32x4_t b) {
   return vandq_u32(a, b);
 }
 
-// CHECK: test_vandq_u64
+// CHECK-LABEL: test_vandq_u64
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vandq_u64(uint64x2_t a, uint64x2_t b) {
   return vandq_u64(a, b);
 }
 
 
-// CHECK: test_vbic_s8
+// CHECK-LABEL: test_vbic_s8
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vbic_s8(int8x8_t a, int8x8_t b) {
   return vbic_s8(a, b);
 }
 
-// CHECK: test_vbic_s16
+// CHECK-LABEL: test_vbic_s16
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vbic_s16(int16x4_t a, int16x4_t b) {
   return vbic_s16(a, b);
 }
 
-// CHECK: test_vbic_s32
+// CHECK-LABEL: test_vbic_s32
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vbic_s32(int32x2_t a, int32x2_t b) {
   return vbic_s32(a, b);
 }
 
-// CHECK: test_vbic_s64
+// CHECK-LABEL: test_vbic_s64
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vbic_s64(int64x1_t a, int64x1_t b) {
   return vbic_s64(a, b);
 }
 
-// CHECK: test_vbic_u8
+// CHECK-LABEL: test_vbic_u8
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vbic_u8(uint8x8_t a, uint8x8_t b) {
   return vbic_u8(a, b);
 }
 
-// CHECK: test_vbic_u16
+// CHECK-LABEL: test_vbic_u16
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vbic_u16(uint16x4_t a, uint16x4_t b) {
   return vbic_u16(a, b);
 }
 
-// CHECK: test_vbic_u32
+// CHECK-LABEL: test_vbic_u32
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vbic_u32(uint32x2_t a, uint32x2_t b) {
   return vbic_u32(a, b);
 }
 
-// CHECK: test_vbic_u64
+// CHECK-LABEL: test_vbic_u64
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vbic_u64(uint64x1_t a, uint64x1_t b) {
   return vbic_u64(a, b);
 }
 
-// CHECK: test_vbicq_s8
+// CHECK-LABEL: test_vbicq_s8
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vbicq_s8(int8x16_t a, int8x16_t b) {
   return vbicq_s8(a, b);
 }
 
-// CHECK: test_vbicq_s16
+// CHECK-LABEL: test_vbicq_s16
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vbicq_s16(int16x8_t a, int16x8_t b) {
   return vbicq_s16(a, b);
 }
 
-// CHECK: test_vbicq_s32
+// CHECK-LABEL: test_vbicq_s32
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vbicq_s32(int32x4_t a, int32x4_t b) {
   return vbicq_s32(a, b);
 }
 
-// CHECK: test_vbicq_s64
+// CHECK-LABEL: test_vbicq_s64
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vbicq_s64(int64x2_t a, int64x2_t b) {
   return vbicq_s64(a, b);
 }
 
-// CHECK: test_vbicq_u8
+// CHECK-LABEL: test_vbicq_u8
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vbicq_u8(uint8x16_t a, uint8x16_t b) {
   return vbicq_u8(a, b);
 }
 
-// CHECK: test_vbicq_u16
+// CHECK-LABEL: test_vbicq_u16
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vbicq_u16(uint16x8_t a, uint16x8_t b) {
   return vbicq_u16(a, b);
 }
 
-// CHECK: test_vbicq_u32
+// CHECK-LABEL: test_vbicq_u32
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vbicq_u32(uint32x4_t a, uint32x4_t b) {
   return vbicq_u32(a, b);
 }
 
-// CHECK: test_vbicq_u64
+// CHECK-LABEL: test_vbicq_u64
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vbicq_u64(uint64x2_t a, uint64x2_t b) {
   return vbicq_u64(a, b);
 }
 
 
-// CHECK: test_vbsl_s8
+// CHECK-LABEL: test_vbsl_s8
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vbsl_s8(uint8x8_t a, int8x8_t b, int8x8_t c) {
   return vbsl_s8(a, b, c);
 }
 
-// CHECK: test_vbsl_s16
+// CHECK-LABEL: test_vbsl_s16
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vbsl_s16(uint16x4_t a, int16x4_t b, int16x4_t c) {
   return vbsl_s16(a, b, c);
 }
 
-// CHECK: test_vbsl_s32
+// CHECK-LABEL: test_vbsl_s32
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vbsl_s32(uint32x2_t a, int32x2_t b, int32x2_t c) {
   return vbsl_s32(a, b, c);
 }
 
-// CHECK: test_vbsl_s64
+// CHECK-LABEL: test_vbsl_s64
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vbsl_s64(uint64x1_t a, int64x1_t b, int64x1_t c) {
   return vbsl_s64(a, b, c);
 }
 
-// CHECK: test_vbsl_u8
+// CHECK-LABEL: test_vbsl_u8
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vbsl_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vbsl_u8(a, b, c);
 }
 
-// CHECK: test_vbsl_u16
+// CHECK-LABEL: test_vbsl_u16
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vbsl_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vbsl_u16(a, b, c);
 }
 
-// CHECK: test_vbsl_u32
+// CHECK-LABEL: test_vbsl_u32
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vbsl_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vbsl_u32(a, b, c);
 }
 
-// CHECK: test_vbsl_u64
+// CHECK-LABEL: test_vbsl_u64
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vbsl_u64(uint64x1_t a, uint64x1_t b, uint64x1_t c) {
   return vbsl_u64(a, b, c);
 }
 
-// CHECK: test_vbsl_f32
+// CHECK-LABEL: test_vbsl_f32
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vbsl_f32(uint32x2_t a, float32x2_t b, float32x2_t c) {
   return vbsl_f32(a, b, c);
 }
 
-// CHECK: test_vbsl_p8
+// CHECK-LABEL: test_vbsl_p8
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vbsl_p8(uint8x8_t a, poly8x8_t b, poly8x8_t c) {
   return vbsl_p8(a, b, c);
 }
 
-// CHECK: test_vbsl_p16
+// CHECK-LABEL: test_vbsl_p16
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4_t test_vbsl_p16(uint16x4_t a, poly16x4_t b, poly16x4_t c) {
   return vbsl_p16(a, b, c);
 }
 
-// CHECK: test_vbslq_s8
+// CHECK-LABEL: test_vbslq_s8
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vbslq_s8(uint8x16_t a, int8x16_t b, int8x16_t c) {
   return vbslq_s8(a, b, c);
 }
 
-// CHECK: test_vbslq_s16
+// CHECK-LABEL: test_vbslq_s16
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vbslq_s16(uint16x8_t a, int16x8_t b, int16x8_t c) {
   return vbslq_s16(a, b, c);
 }
 
-// CHECK: test_vbslq_s32
+// CHECK-LABEL: test_vbslq_s32
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vbslq_s32(uint32x4_t a, int32x4_t b, int32x4_t c) {
   return vbslq_s32(a, b, c);
 }
 
-// CHECK: test_vbslq_s64
+// CHECK-LABEL: test_vbslq_s64
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vbslq_s64(uint64x2_t a, int64x2_t b, int64x2_t c) {
   return vbslq_s64(a, b, c);
 }
 
-// CHECK: test_vbslq_u8
+// CHECK-LABEL: test_vbslq_u8
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vbslq_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
   return vbslq_u8(a, b, c);
 }
 
-// CHECK: test_vbslq_u16
+// CHECK-LABEL: test_vbslq_u16
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vbslq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t c) {
   return vbslq_u16(a, b, c);
 }
 
-// CHECK: test_vbslq_u32
+// CHECK-LABEL: test_vbslq_u32
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vbslq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
   return vbslq_u32(a, b, c);
 }
 
-// CHECK: test_vbslq_u64
+// CHECK-LABEL: test_vbslq_u64
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vbslq_u64(uint64x2_t a, uint64x2_t b, uint64x2_t c) {
   return vbslq_u64(a, b, c);
 }
 
-// CHECK: test_vbslq_f32
+// CHECK-LABEL: test_vbslq_f32
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vbslq_f32(uint32x4_t a, float32x4_t b, float32x4_t c) {
   return vbslq_f32(a, b, c);
 }
 
-// CHECK: test_vbslq_p8
+// CHECK-LABEL: test_vbslq_p8
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vbslq_p8(uint8x16_t a, poly8x16_t b, poly8x16_t c) {
   return vbslq_p8(a, b, c);
 }
 
-// CHECK: test_vbslq_p16
+// CHECK-LABEL: test_vbslq_p16
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8_t test_vbslq_p16(uint16x8_t a, poly16x8_t b, poly16x8_t c) {
   return vbslq_p16(a, b, c);
 }
 
 
-// CHECK: test_vcage_f32
+// CHECK-LABEL: test_vcage_f32
 // CHECK: vacge.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcage_f32(float32x2_t a, float32x2_t b) {
   return vcage_f32(a, b);
 }
 
-// CHECK: test_vcageq_f32
+// CHECK-LABEL: test_vcageq_f32
 // CHECK: vacge.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcageq_f32(float32x4_t a, float32x4_t b) {
   return vcageq_f32(a, b);
 }
 
 
-// CHECK: test_vcagt_f32
+// CHECK-LABEL: test_vcagt_f32
 // CHECK: vacgt.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcagt_f32(float32x2_t a, float32x2_t b) {
   return vcagt_f32(a, b);
 }
 
-// CHECK: test_vcagtq_f32
+// CHECK-LABEL: test_vcagtq_f32
 // CHECK: vacgt.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcagtq_f32(float32x4_t a, float32x4_t b) {
   return vcagtq_f32(a, b);
 }
 
 
-// CHECK: test_vcale_f32
+// CHECK-LABEL: test_vcale_f32
 // CHECK: vacge.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcale_f32(float32x2_t a, float32x2_t b) {
   return vcale_f32(a, b);
 }
 
-// CHECK: test_vcaleq_f32
+// CHECK-LABEL: test_vcaleq_f32
 // CHECK: vacge.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcaleq_f32(float32x4_t a, float32x4_t b) {
   return vcaleq_f32(a, b);
 }
 
 
-// CHECK: test_vcalt_f32
+// CHECK-LABEL: test_vcalt_f32
 // CHECK: vacgt.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcalt_f32(float32x2_t a, float32x2_t b) {
   return vcalt_f32(a, b);
 }
 
-// CHECK: test_vcaltq_f32
+// CHECK-LABEL: test_vcaltq_f32
 // CHECK: vacgt.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcaltq_f32(float32x4_t a, float32x4_t b) {
   return vcaltq_f32(a, b);
 }
 
 
-// CHECK: test_vceq_s8
+// CHECK-LABEL: test_vceq_s8
 // CHECK: vceq.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vceq_s8(int8x8_t a, int8x8_t b) {
   return vceq_s8(a, b);
 }
 
-// CHECK: test_vceq_s16
+// CHECK-LABEL: test_vceq_s16
 // CHECK: vceq.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vceq_s16(int16x4_t a, int16x4_t b) {
   return vceq_s16(a, b);
 }
 
-// CHECK: test_vceq_s32
+// CHECK-LABEL: test_vceq_s32
 // CHECK: vceq.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vceq_s32(int32x2_t a, int32x2_t b) {
   return vceq_s32(a, b);
 }
 
-// CHECK: test_vceq_f32
+// CHECK-LABEL: test_vceq_f32
 // CHECK: vceq.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vceq_f32(float32x2_t a, float32x2_t b) {
   return vceq_f32(a, b);
 }
 
-// CHECK: test_vceq_u8
+// CHECK-LABEL: test_vceq_u8
 // CHECK: vceq.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vceq_u8(uint8x8_t a, uint8x8_t b) {
   return vceq_u8(a, b);
 }
 
-// CHECK: test_vceq_u16
+// CHECK-LABEL: test_vceq_u16
 // CHECK: vceq.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vceq_u16(uint16x4_t a, uint16x4_t b) {
   return vceq_u16(a, b);
 }
 
-// CHECK: test_vceq_u32
+// CHECK-LABEL: test_vceq_u32
 // CHECK: vceq.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vceq_u32(uint32x2_t a, uint32x2_t b) {
   return vceq_u32(a, b);
 }
 
-// CHECK: test_vceq_p8
+// CHECK-LABEL: test_vceq_p8
 // CHECK: vceq.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vceq_p8(poly8x8_t a, poly8x8_t b) {
   return vceq_p8(a, b);
 }
 
-// CHECK: test_vceqq_s8
+// CHECK-LABEL: test_vceqq_s8
 // CHECK: vceq.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vceqq_s8(int8x16_t a, int8x16_t b) {
   return vceqq_s8(a, b);
 }
 
-// CHECK: test_vceqq_s16
+// CHECK-LABEL: test_vceqq_s16
 // CHECK: vceq.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vceqq_s16(int16x8_t a, int16x8_t b) {
   return vceqq_s16(a, b);
 }
 
-// CHECK: test_vceqq_s32
+// CHECK-LABEL: test_vceqq_s32
 // CHECK: vceq.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vceqq_s32(int32x4_t a, int32x4_t b) {
   return vceqq_s32(a, b);
 }
 
-// CHECK: test_vceqq_f32
+// CHECK-LABEL: test_vceqq_f32
 // CHECK: vceq.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vceqq_f32(float32x4_t a, float32x4_t b) {
   return vceqq_f32(a, b);
 }
 
-// CHECK: test_vceqq_u8
+// CHECK-LABEL: test_vceqq_u8
 // CHECK: vceq.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vceqq_u8(uint8x16_t a, uint8x16_t b) {
   return vceqq_u8(a, b);
 }
 
-// CHECK: test_vceqq_u16
+// CHECK-LABEL: test_vceqq_u16
 // CHECK: vceq.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vceqq_u16(uint16x8_t a, uint16x8_t b) {
   return vceqq_u16(a, b);
 }
 
-// CHECK: test_vceqq_u32
+// CHECK-LABEL: test_vceqq_u32
 // CHECK: vceq.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vceqq_u32(uint32x4_t a, uint32x4_t b) {
   return vceqq_u32(a, b);
 }
 
-// CHECK: test_vceqq_p8
+// CHECK-LABEL: test_vceqq_p8
 // CHECK: vceq.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vceqq_p8(poly8x16_t a, poly8x16_t b) {
   return vceqq_p8(a, b);
 }
 
 
-// CHECK: test_vcge_s8
+// CHECK-LABEL: test_vcge_s8
 // CHECK: vcge.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcge_s8(int8x8_t a, int8x8_t b) {
   return vcge_s8(a, b);
 }
 
-// CHECK: test_vcge_s16
+// CHECK-LABEL: test_vcge_s16
 // CHECK: vcge.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcge_s16(int16x4_t a, int16x4_t b) {
   return vcge_s16(a, b);
 }
 
-// CHECK: test_vcge_s32
+// CHECK-LABEL: test_vcge_s32
 // CHECK: vcge.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcge_s32(int32x2_t a, int32x2_t b) {
   return vcge_s32(a, b);
 }
 
-// CHECK: test_vcge_f32
+// CHECK-LABEL: test_vcge_f32
 // CHECK: vcge.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcge_f32(float32x2_t a, float32x2_t b) {
   return vcge_f32(a, b);
 }
 
-// CHECK: test_vcge_u8
+// CHECK-LABEL: test_vcge_u8
 // CHECK: vcge.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcge_u8(uint8x8_t a, uint8x8_t b) {
   return vcge_u8(a, b);
 }
 
-// CHECK: test_vcge_u16
+// CHECK-LABEL: test_vcge_u16
 // CHECK: vcge.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcge_u16(uint16x4_t a, uint16x4_t b) {
   return vcge_u16(a, b);
 }
 
-// CHECK: test_vcge_u32
+// CHECK-LABEL: test_vcge_u32
 // CHECK: vcge.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcge_u32(uint32x2_t a, uint32x2_t b) {
   return vcge_u32(a, b);
 }
 
-// CHECK: test_vcgeq_s8
+// CHECK-LABEL: test_vcgeq_s8
 // CHECK: vcge.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcgeq_s8(int8x16_t a, int8x16_t b) {
   return vcgeq_s8(a, b);
 }
 
-// CHECK: test_vcgeq_s16
+// CHECK-LABEL: test_vcgeq_s16
 // CHECK: vcge.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcgeq_s16(int16x8_t a, int16x8_t b) {
   return vcgeq_s16(a, b);
 }
 
-// CHECK: test_vcgeq_s32
+// CHECK-LABEL: test_vcgeq_s32
 // CHECK: vcge.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgeq_s32(int32x4_t a, int32x4_t b) {
   return vcgeq_s32(a, b);
 }
 
-// CHECK: test_vcgeq_f32
+// CHECK-LABEL: test_vcgeq_f32
 // CHECK: vcge.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgeq_f32(float32x4_t a, float32x4_t b) {
   return vcgeq_f32(a, b);
 }
 
-// CHECK: test_vcgeq_u8
+// CHECK-LABEL: test_vcgeq_u8
 // CHECK: vcge.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcgeq_u8(uint8x16_t a, uint8x16_t b) {
   return vcgeq_u8(a, b);
 }
 
-// CHECK: test_vcgeq_u16
+// CHECK-LABEL: test_vcgeq_u16
 // CHECK: vcge.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcgeq_u16(uint16x8_t a, uint16x8_t b) {
   return vcgeq_u16(a, b);
 }
 
-// CHECK: test_vcgeq_u32
+// CHECK-LABEL: test_vcgeq_u32
 // CHECK: vcge.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgeq_u32(uint32x4_t a, uint32x4_t b) {
   return vcgeq_u32(a, b);
 }
 
 
-// CHECK: test_vcgt_s8
+// CHECK-LABEL: test_vcgt_s8
 // CHECK: vcgt.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcgt_s8(int8x8_t a, int8x8_t b) {
   return vcgt_s8(a, b);
 }
 
-// CHECK: test_vcgt_s16
+// CHECK-LABEL: test_vcgt_s16
 // CHECK: vcgt.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcgt_s16(int16x4_t a, int16x4_t b) {
   return vcgt_s16(a, b);
 }
 
-// CHECK: test_vcgt_s32
+// CHECK-LABEL: test_vcgt_s32
 // CHECK: vcgt.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcgt_s32(int32x2_t a, int32x2_t b) {
   return vcgt_s32(a, b);
 }
 
-// CHECK: test_vcgt_f32
+// CHECK-LABEL: test_vcgt_f32
 // CHECK: vcgt.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcgt_f32(float32x2_t a, float32x2_t b) {
   return vcgt_f32(a, b);
 }
 
-// CHECK: test_vcgt_u8
+// CHECK-LABEL: test_vcgt_u8
 // CHECK: vcgt.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcgt_u8(uint8x8_t a, uint8x8_t b) {
   return vcgt_u8(a, b);
 }
 
-// CHECK: test_vcgt_u16
+// CHECK-LABEL: test_vcgt_u16
 // CHECK: vcgt.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcgt_u16(uint16x4_t a, uint16x4_t b) {
   return vcgt_u16(a, b);
 }
 
-// CHECK: test_vcgt_u32
+// CHECK-LABEL: test_vcgt_u32
 // CHECK: vcgt.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcgt_u32(uint32x2_t a, uint32x2_t b) {
   return vcgt_u32(a, b);
 }
 
-// CHECK: test_vcgtq_s8
+// CHECK-LABEL: test_vcgtq_s8
 // CHECK: vcgt.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcgtq_s8(int8x16_t a, int8x16_t b) {
   return vcgtq_s8(a, b);
 }
 
-// CHECK: test_vcgtq_s16
+// CHECK-LABEL: test_vcgtq_s16
 // CHECK: vcgt.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcgtq_s16(int16x8_t a, int16x8_t b) {
   return vcgtq_s16(a, b);
 }
 
-// CHECK: test_vcgtq_s32
+// CHECK-LABEL: test_vcgtq_s32
 // CHECK: vcgt.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgtq_s32(int32x4_t a, int32x4_t b) {
   return vcgtq_s32(a, b);
 }
 
-// CHECK: test_vcgtq_f32
+// CHECK-LABEL: test_vcgtq_f32
 // CHECK: vcgt.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgtq_f32(float32x4_t a, float32x4_t b) {
   return vcgtq_f32(a, b);
 }
 
-// CHECK: test_vcgtq_u8
+// CHECK-LABEL: test_vcgtq_u8
 // CHECK: vcgt.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcgtq_u8(uint8x16_t a, uint8x16_t b) {
   return vcgtq_u8(a, b);
 }
 
-// CHECK: test_vcgtq_u16
+// CHECK-LABEL: test_vcgtq_u16
 // CHECK: vcgt.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcgtq_u16(uint16x8_t a, uint16x8_t b) {
   return vcgtq_u16(a, b);
 }
 
-// CHECK: test_vcgtq_u32
+// CHECK-LABEL: test_vcgtq_u32
 // CHECK: vcgt.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgtq_u32(uint32x4_t a, uint32x4_t b) {
   return vcgtq_u32(a, b);
 }
 
 
-// CHECK: test_vcle_s8
+// CHECK-LABEL: test_vcle_s8
 // CHECK: vcge.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcle_s8(int8x8_t a, int8x8_t b) {
   return vcle_s8(a, b);
 }
 
-// CHECK: test_vcle_s16
+// CHECK-LABEL: test_vcle_s16
 // CHECK: vcge.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcle_s16(int16x4_t a, int16x4_t b) {
   return vcle_s16(a, b);
 }
 
-// CHECK: test_vcle_s32
+// CHECK-LABEL: test_vcle_s32
 // CHECK: vcge.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcle_s32(int32x2_t a, int32x2_t b) {
   return vcle_s32(a, b);
 }
 
-// CHECK: test_vcle_f32
+// CHECK-LABEL: test_vcle_f32
 // CHECK: vcge.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcle_f32(float32x2_t a, float32x2_t b) {
   return vcle_f32(a, b);
 }
 
-// CHECK: test_vcle_u8
+// CHECK-LABEL: test_vcle_u8
 // CHECK: vcge.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcle_u8(uint8x8_t a, uint8x8_t b) {
   return vcle_u8(a, b);
 }
 
-// CHECK: test_vcle_u16
+// CHECK-LABEL: test_vcle_u16
 // CHECK: vcge.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcle_u16(uint16x4_t a, uint16x4_t b) {
   return vcle_u16(a, b);
 }
 
-// CHECK: test_vcle_u32
+// CHECK-LABEL: test_vcle_u32
 // CHECK: vcge.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcle_u32(uint32x2_t a, uint32x2_t b) {
   return vcle_u32(a, b);
 }
 
-// CHECK: test_vcleq_s8
+// CHECK-LABEL: test_vcleq_s8
 // CHECK: vcge.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcleq_s8(int8x16_t a, int8x16_t b) {
   return vcleq_s8(a, b);
 }
 
-// CHECK: test_vcleq_s16
+// CHECK-LABEL: test_vcleq_s16
 // CHECK: vcge.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcleq_s16(int16x8_t a, int16x8_t b) {
   return vcleq_s16(a, b);
 }
 
-// CHECK: test_vcleq_s32
+// CHECK-LABEL: test_vcleq_s32
 // CHECK: vcge.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcleq_s32(int32x4_t a, int32x4_t b) {
   return vcleq_s32(a, b);
 }
 
-// CHECK: test_vcleq_f32
+// CHECK-LABEL: test_vcleq_f32
 // CHECK: vcge.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcleq_f32(float32x4_t a, float32x4_t b) {
   return vcleq_f32(a, b);
 }
 
-// CHECK: test_vcleq_u8
+// CHECK-LABEL: test_vcleq_u8
 // CHECK: vcge.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcleq_u8(uint8x16_t a, uint8x16_t b) {
   return vcleq_u8(a, b);
 }
 
-// CHECK: test_vcleq_u16
+// CHECK-LABEL: test_vcleq_u16
 // CHECK: vcge.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcleq_u16(uint16x8_t a, uint16x8_t b) {
   return vcleq_u16(a, b);
 }
 
-// CHECK: test_vcleq_u32
+// CHECK-LABEL: test_vcleq_u32
 // CHECK: vcge.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcleq_u32(uint32x4_t a, uint32x4_t b) {
   return vcleq_u32(a, b);
 }
 
 
-// CHECK: test_vcls_s8
+// CHECK-LABEL: test_vcls_s8
 // CHECK: vcls.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vcls_s8(int8x8_t a) {
   return vcls_s8(a);
 }
 
-// CHECK: test_vcls_s16
+// CHECK-LABEL: test_vcls_s16
 // CHECK: vcls.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vcls_s16(int16x4_t a) {
   return vcls_s16(a);
 }
 
-// CHECK: test_vcls_s32
+// CHECK-LABEL: test_vcls_s32
 // CHECK: vcls.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vcls_s32(int32x2_t a) {
   return vcls_s32(a);
 }
 
-// CHECK: test_vclsq_s8
+// CHECK-LABEL: test_vclsq_s8
 // CHECK: vcls.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vclsq_s8(int8x16_t a) {
   return vclsq_s8(a);
 }
 
-// CHECK: test_vclsq_s16
+// CHECK-LABEL: test_vclsq_s16
 // CHECK: vcls.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vclsq_s16(int16x8_t a) {
   return vclsq_s16(a);
 }
 
-// CHECK: test_vclsq_s32
+// CHECK-LABEL: test_vclsq_s32
 // CHECK: vcls.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vclsq_s32(int32x4_t a) {
   return vclsq_s32(a);
 }
 
 
-// CHECK: test_vclt_s8
+// CHECK-LABEL: test_vclt_s8
 // CHECK: vcgt.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vclt_s8(int8x8_t a, int8x8_t b) {
   return vclt_s8(a, b);
 }
 
-// CHECK: test_vclt_s16
+// CHECK-LABEL: test_vclt_s16
 // CHECK: vcgt.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vclt_s16(int16x4_t a, int16x4_t b) {
   return vclt_s16(a, b);
 }
 
-// CHECK: test_vclt_s32
+// CHECK-LABEL: test_vclt_s32
 // CHECK: vcgt.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vclt_s32(int32x2_t a, int32x2_t b) {
   return vclt_s32(a, b);
 }
 
-// CHECK: test_vclt_f32
+// CHECK-LABEL: test_vclt_f32
 // CHECK: vcgt.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vclt_f32(float32x2_t a, float32x2_t b) {
   return vclt_f32(a, b);
 }
 
-// CHECK: test_vclt_u8
+// CHECK-LABEL: test_vclt_u8
 // CHECK: vcgt.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vclt_u8(uint8x8_t a, uint8x8_t b) {
   return vclt_u8(a, b);
 }
 
-// CHECK: test_vclt_u16
+// CHECK-LABEL: test_vclt_u16
 // CHECK: vcgt.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vclt_u16(uint16x4_t a, uint16x4_t b) {
   return vclt_u16(a, b);
 }
 
-// CHECK: test_vclt_u32
+// CHECK-LABEL: test_vclt_u32
 // CHECK: vcgt.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vclt_u32(uint32x2_t a, uint32x2_t b) {
   return vclt_u32(a, b);
 }
 
-// CHECK: test_vcltq_s8
+// CHECK-LABEL: test_vcltq_s8
 // CHECK: vcgt.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcltq_s8(int8x16_t a, int8x16_t b) {
   return vcltq_s8(a, b);
 }
 
-// CHECK: test_vcltq_s16
+// CHECK-LABEL: test_vcltq_s16
 // CHECK: vcgt.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcltq_s16(int16x8_t a, int16x8_t b) {
   return vcltq_s16(a, b);
 }
 
-// CHECK: test_vcltq_s32
+// CHECK-LABEL: test_vcltq_s32
 // CHECK: vcgt.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcltq_s32(int32x4_t a, int32x4_t b) {
   return vcltq_s32(a, b);
 }
 
-// CHECK: test_vcltq_f32
+// CHECK-LABEL: test_vcltq_f32
 // CHECK: vcgt.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcltq_f32(float32x4_t a, float32x4_t b) {
   return vcltq_f32(a, b);
 }
 
-// CHECK: test_vcltq_u8
+// CHECK-LABEL: test_vcltq_u8
 // CHECK: vcgt.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcltq_u8(uint8x16_t a, uint8x16_t b) {
   return vcltq_u8(a, b);
 }
 
-// CHECK: test_vcltq_u16
+// CHECK-LABEL: test_vcltq_u16
 // CHECK: vcgt.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcltq_u16(uint16x8_t a, uint16x8_t b) {
   return vcltq_u16(a, b);
 }
 
-// CHECK: test_vcltq_u32
+// CHECK-LABEL: test_vcltq_u32
 // CHECK: vcgt.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcltq_u32(uint32x4_t a, uint32x4_t b) {
   return vcltq_u32(a, b);
 }
 
 
-// CHECK: test_vclz_s8
+// CHECK-LABEL: test_vclz_s8
 // CHECK: vclz.i8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vclz_s8(int8x8_t a) {
   return vclz_s8(a);
 }
 
-// CHECK: test_vclz_s16
+// CHECK-LABEL: test_vclz_s16
 // CHECK: vclz.i16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vclz_s16(int16x4_t a) {
   return vclz_s16(a);
 }
 
-// CHECK: test_vclz_s32
+// CHECK-LABEL: test_vclz_s32
 // CHECK: vclz.i32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vclz_s32(int32x2_t a) {
   return vclz_s32(a);
 }
 
-// CHECK: test_vclz_u8
+// CHECK-LABEL: test_vclz_u8
 // CHECK: vclz.i8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vclz_u8(uint8x8_t a) {
   return vclz_u8(a);
 }
 
-// CHECK: test_vclz_u16
+// CHECK-LABEL: test_vclz_u16
 // CHECK: vclz.i16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vclz_u16(uint16x4_t a) {
   return vclz_u16(a);
 }
 
-// CHECK: test_vclz_u32
+// CHECK-LABEL: test_vclz_u32
 // CHECK: vclz.i32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vclz_u32(uint32x2_t a) {
   return vclz_u32(a);
 }
 
-// CHECK: test_vclzq_s8
+// CHECK-LABEL: test_vclzq_s8
 // CHECK: vclz.i8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vclzq_s8(int8x16_t a) {
   return vclzq_s8(a);
 }
 
-// CHECK: test_vclzq_s16
+// CHECK-LABEL: test_vclzq_s16
 // CHECK: vclz.i16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vclzq_s16(int16x8_t a) {
   return vclzq_s16(a);
 }
 
-// CHECK: test_vclzq_s32
+// CHECK-LABEL: test_vclzq_s32
 // CHECK: vclz.i32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vclzq_s32(int32x4_t a) {
   return vclzq_s32(a);
 }
 
-// CHECK: test_vclzq_u8
+// CHECK-LABEL: test_vclzq_u8
 // CHECK: vclz.i8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vclzq_u8(uint8x16_t a) {
   return vclzq_u8(a);
 }
 
-// CHECK: test_vclzq_u16
+// CHECK-LABEL: test_vclzq_u16
 // CHECK: vclz.i16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vclzq_u16(uint16x8_t a) {
   return vclzq_u16(a);
 }
 
-// CHECK: test_vclzq_u32
+// CHECK-LABEL: test_vclzq_u32
 // CHECK: vclz.i32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vclzq_u32(uint32x4_t a) {
   return vclzq_u32(a);
 }
 
 
-// CHECK: test_vcnt_u8
+// CHECK-LABEL: test_vcnt_u8
 // CHECK: vcnt.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcnt_u8(uint8x8_t a) {
   return vcnt_u8(a);
 }
 
-// CHECK: test_vcnt_s8
+// CHECK-LABEL: test_vcnt_s8
 // CHECK: vcnt.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vcnt_s8(int8x8_t a) {
   return vcnt_s8(a);
 }
 
-// CHECK: test_vcnt_p8
+// CHECK-LABEL: test_vcnt_p8
 // CHECK: vcnt.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vcnt_p8(poly8x8_t a) {
   return vcnt_p8(a);
 }
 
-// CHECK: test_vcntq_u8
+// CHECK-LABEL: test_vcntq_u8
 // CHECK: vcnt.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcntq_u8(uint8x16_t a) {
   return vcntq_u8(a);
 }
 
-// CHECK: test_vcntq_s8
+// CHECK-LABEL: test_vcntq_s8
 // CHECK: vcnt.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vcntq_s8(int8x16_t a) {
   return vcntq_s8(a);
 }
 
-// CHECK: test_vcntq_p8
+// CHECK-LABEL: test_vcntq_p8
 // CHECK: vcnt.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vcntq_p8(poly8x16_t a) {
   return vcntq_p8(a);
 }
 
 
-// CHECK: test_vcombine_s8
+// CHECK-LABEL: test_vcombine_s8
 int8x16_t test_vcombine_s8(int8x8_t a, int8x8_t b) {
   return vcombine_s8(a, b);
 }
 
-// CHECK: test_vcombine_s16
+// CHECK-LABEL: test_vcombine_s16
 int16x8_t test_vcombine_s16(int16x4_t a, int16x4_t b) {
   return vcombine_s16(a, b);
 }
 
-// CHECK: test_vcombine_s32
+// CHECK-LABEL: test_vcombine_s32
 int32x4_t test_vcombine_s32(int32x2_t a, int32x2_t b) {
   return vcombine_s32(a, b);
 }
 
-// CHECK: test_vcombine_s64
+// CHECK-LABEL: test_vcombine_s64
 int64x2_t test_vcombine_s64(int64x1_t a, int64x1_t b) {
   return vcombine_s64(a, b);
 }
 
-// CHECK: test_vcombine_f16
+// CHECK-LABEL: test_vcombine_f16
 float16x8_t test_vcombine_f16(float16x4_t a, float16x4_t b) {
   return vcombine_f16(a, b);
 }
 
-// CHECK: test_vcombine_f32
+// CHECK-LABEL: test_vcombine_f32
 float32x4_t test_vcombine_f32(float32x2_t a, float32x2_t b) {
   return vcombine_f32(a, b);
 }
 
-// CHECK: test_vcombine_u8
+// CHECK-LABEL: test_vcombine_u8
 uint8x16_t test_vcombine_u8(uint8x8_t a, uint8x8_t b) {
   return vcombine_u8(a, b);
 }
 
-// CHECK: test_vcombine_u16
+// CHECK-LABEL: test_vcombine_u16
 uint16x8_t test_vcombine_u16(uint16x4_t a, uint16x4_t b) {
   return vcombine_u16(a, b);
 }
 
-// CHECK: test_vcombine_u32
+// CHECK-LABEL: test_vcombine_u32
 uint32x4_t test_vcombine_u32(uint32x2_t a, uint32x2_t b) {
   return vcombine_u32(a, b);
 }
 
-// CHECK: test_vcombine_u64
+// CHECK-LABEL: test_vcombine_u64
 uint64x2_t test_vcombine_u64(uint64x1_t a, uint64x1_t b) {
   return vcombine_u64(a, b);
 }
 
-// CHECK: test_vcombine_p8
+// CHECK-LABEL: test_vcombine_p8
 poly8x16_t test_vcombine_p8(poly8x8_t a, poly8x8_t b) {
   return vcombine_p8(a, b);
 }
 
-// CHECK: test_vcombine_p16
+// CHECK-LABEL: test_vcombine_p16
 poly16x8_t test_vcombine_p16(poly16x4_t a, poly16x4_t b) {
   return vcombine_p16(a, b);
 }
 
 
-// CHECK: test_vcreate_s8
+// CHECK-LABEL: test_vcreate_s8
 int8x8_t test_vcreate_s8(uint64_t a) {
   return vcreate_s8(a);
 }
 
-// CHECK: test_vcreate_s16
+// CHECK-LABEL: test_vcreate_s16
 int16x4_t test_vcreate_s16(uint64_t a) {
   return vcreate_s16(a);
 }
 
-// CHECK: test_vcreate_s32
+// CHECK-LABEL: test_vcreate_s32
 int32x2_t test_vcreate_s32(uint64_t a) {
   return vcreate_s32(a);
 }
 
-// CHECK: test_vcreate_f16
+// CHECK-LABEL: test_vcreate_f16
 float16x4_t test_vcreate_f16(uint64_t a) {
   return vcreate_f16(a);
 }
 
-// CHECK: test_vcreate_f32
+// CHECK-LABEL: test_vcreate_f32
 float32x2_t test_vcreate_f32(uint64_t a) {
   return vcreate_f32(a);
 }
 
-// CHECK: test_vcreate_u8
+// CHECK-LABEL: test_vcreate_u8
 uint8x8_t test_vcreate_u8(uint64_t a) {
   return vcreate_u8(a);
 }
 
-// CHECK: test_vcreate_u16
+// CHECK-LABEL: test_vcreate_u16
 uint16x4_t test_vcreate_u16(uint64_t a) {
   return vcreate_u16(a);
 }
 
-// CHECK: test_vcreate_u32
+// CHECK-LABEL: test_vcreate_u32
 uint32x2_t test_vcreate_u32(uint64_t a) {
   return vcreate_u32(a);
 }
 
-// CHECK: test_vcreate_u64
+// CHECK-LABEL: test_vcreate_u64
 uint64x1_t test_vcreate_u64(uint64_t a) {
   return vcreate_u64(a);
 }
 
-// CHECK: test_vcreate_p8
+// CHECK-LABEL: test_vcreate_p8
 poly8x8_t test_vcreate_p8(uint64_t a) {
   return vcreate_p8(a);
 }
 
-// CHECK: test_vcreate_p16
+// CHECK-LABEL: test_vcreate_p16
 poly16x4_t test_vcreate_p16(uint64_t a) {
   return vcreate_p16(a);
 }
 
-// CHECK: test_vcreate_s64
+// CHECK-LABEL: test_vcreate_s64
 int64x1_t test_vcreate_s64(uint64_t a) {
   return vcreate_s64(a);
 }
 
 
-// CHECK: test_vcvt_f16_f32
+// CHECK-LABEL: test_vcvt_f16_f32
 // CHECK: vcvt.f16.f32 d{{[0-9]+}}, q{{[0-9]+}}
 float16x4_t test_vcvt_f16_f32(float32x4_t a) {
   return vcvt_f16_f32(a);
 }
 
 
-// CHECK: test_vcvt_f32_s32
+// CHECK-LABEL: test_vcvt_f32_s32
 // CHECK: vcvt.f32.s32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vcvt_f32_s32(int32x2_t a) {
   return vcvt_f32_s32(a);
 }
 
-// CHECK: test_vcvt_f32_u32
+// CHECK-LABEL: test_vcvt_f32_u32
 // CHECK: vcvt.f32.u32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vcvt_f32_u32(uint32x2_t a) {
   return vcvt_f32_u32(a);
 }
 
-// CHECK: test_vcvtq_f32_s32
+// CHECK-LABEL: test_vcvtq_f32_s32
 // CHECK: vcvt.f32.s32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vcvtq_f32_s32(int32x4_t a) {
   return vcvtq_f32_s32(a);
 }
 
-// CHECK: test_vcvtq_f32_u32
+// CHECK-LABEL: test_vcvtq_f32_u32
 // CHECK: vcvt.f32.u32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vcvtq_f32_u32(uint32x4_t a) {
   return vcvtq_f32_u32(a);
 }
 
 
-// CHECK: test_vcvt_f32_f16
+// CHECK-LABEL: test_vcvt_f32_f16
 // CHECK: vcvt.f32.f16
 float32x4_t test_vcvt_f32_f16(float16x4_t a) {
   return vcvt_f32_f16(a);
 }
 
 
-// CHECK: test_vcvt_n_f32_s32
+// CHECK-LABEL: test_vcvt_n_f32_s32
 // CHECK: vcvt.f32.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 float32x2_t test_vcvt_n_f32_s32(int32x2_t a) {
   return vcvt_n_f32_s32(a, 1);
 }
 
-// CHECK: test_vcvt_n_f32_u32
+// CHECK-LABEL: test_vcvt_n_f32_u32
 // CHECK: vcvt.f32.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 float32x2_t test_vcvt_n_f32_u32(uint32x2_t a) {
   return vcvt_n_f32_u32(a, 1);
 }
 
-// CHECK: test_vcvtq_n_f32_s32
+// CHECK-LABEL: test_vcvtq_n_f32_s32
 // CHECK: vcvt.f32.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 float32x4_t test_vcvtq_n_f32_s32(int32x4_t a) {
   return vcvtq_n_f32_s32(a, 3);
 }
 
-// CHECK: test_vcvtq_n_f32_u32
+// CHECK-LABEL: test_vcvtq_n_f32_u32
 // CHECK: vcvt.f32.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 float32x4_t test_vcvtq_n_f32_u32(uint32x4_t a) {
   return vcvtq_n_f32_u32(a, 3);
 }
 
 
-// CHECK: test_vcvt_n_s32_f32
+// CHECK-LABEL: test_vcvt_n_s32_f32
 // CHECK: vcvt.s32.f32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vcvt_n_s32_f32(float32x2_t a) {
   return vcvt_n_s32_f32(a, 1);
 }
 
-// CHECK: test_vcvtq_n_s32_f32
+// CHECK-LABEL: test_vcvtq_n_s32_f32
 // CHECK: vcvt.s32.f32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vcvtq_n_s32_f32(float32x4_t a) {
   return vcvtq_n_s32_f32(a, 3);
 }
 
 
-// CHECK: test_vcvt_n_u32_f32
+// CHECK-LABEL: test_vcvt_n_u32_f32
 // CHECK: vcvt.u32.f32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vcvt_n_u32_f32(float32x2_t a) {
   return vcvt_n_u32_f32(a, 1);
 }
 
-// CHECK: test_vcvtq_n_u32_f32
+// CHECK-LABEL: test_vcvtq_n_u32_f32
 // CHECK: vcvt.u32.f32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vcvtq_n_u32_f32(float32x4_t a) {
   return vcvtq_n_u32_f32(a, 3);
 }
 
 
-// CHECK: test_vcvt_s32_f32
+// CHECK-LABEL: test_vcvt_s32_f32
 // CHECK: vcvt.s32.f32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vcvt_s32_f32(float32x2_t a) {
   return vcvt_s32_f32(a);
 }
 
-// CHECK: test_vcvtq_s32_f32
+// CHECK-LABEL: test_vcvtq_s32_f32
 // CHECK: vcvt.s32.f32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vcvtq_s32_f32(float32x4_t a) {
   return vcvtq_s32_f32(a);
 }
 
 
-// CHECK: test_vcvt_u32_f32
+// CHECK-LABEL: test_vcvt_u32_f32
 // CHECK: vcvt.u32.f32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcvt_u32_f32(float32x2_t a) {
   return vcvt_u32_f32(a);
 }
 
-// CHECK: test_vcvtq_u32_f32
+// CHECK-LABEL: test_vcvtq_u32_f32
 // CHECK: vcvt.u32.f32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcvtq_u32_f32(float32x4_t a) {
   return vcvtq_u32_f32(a);
 }
 
 
-// CHECK: test_vdup_lane_u8
+// CHECK-LABEL: test_vdup_lane_u8
 // CHECK: vdup.8 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint8x8_t test_vdup_lane_u8(uint8x8_t a) {
   return vdup_lane_u8(a, 7);
 }
 
-// CHECK: test_vdup_lane_u16
+// CHECK-LABEL: test_vdup_lane_u16
 // CHECK: vdup.16 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x4_t test_vdup_lane_u16(uint16x4_t a) {
   return vdup_lane_u16(a, 3);
 }
 
-// CHECK: test_vdup_lane_u32
+// CHECK-LABEL: test_vdup_lane_u32
 // CHECK: vdup.32 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x2_t test_vdup_lane_u32(uint32x2_t a) {
   return vdup_lane_u32(a, 1);
 }
 
-// CHECK: test_vdup_lane_s8
+// CHECK-LABEL: test_vdup_lane_s8
 // CHECK: vdup.8 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int8x8_t test_vdup_lane_s8(int8x8_t a) {
   return vdup_lane_s8(a, 7);
 }
 
-// CHECK: test_vdup_lane_s16
+// CHECK-LABEL: test_vdup_lane_s16
 // CHECK: vdup.16 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vdup_lane_s16(int16x4_t a) {
   return vdup_lane_s16(a, 3);
 }
 
-// CHECK: test_vdup_lane_s32
+// CHECK-LABEL: test_vdup_lane_s32
 // CHECK: vdup.32 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vdup_lane_s32(int32x2_t a) {
   return vdup_lane_s32(a, 1);
 }
 
-// CHECK: test_vdup_lane_p8
+// CHECK-LABEL: test_vdup_lane_p8
 // CHECK: vdup.8 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 poly8x8_t test_vdup_lane_p8(poly8x8_t a) {
   return vdup_lane_p8(a, 7);
 }
 
-// CHECK: test_vdup_lane_p16
+// CHECK-LABEL: test_vdup_lane_p16
 // CHECK: vdup.16 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 poly16x4_t test_vdup_lane_p16(poly16x4_t a) {
   return vdup_lane_p16(a, 3);
 }
 
-// CHECK: test_vdup_lane_f32
+// CHECK-LABEL: test_vdup_lane_f32
 // CHECK: vdup.32 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x2_t test_vdup_lane_f32(float32x2_t a) {
   return vdup_lane_f32(a, 1);
 }
 
-// CHECK: test_vdupq_lane_u8
+// CHECK-LABEL: test_vdupq_lane_u8
 // CHECK: vdup.8 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint8x16_t test_vdupq_lane_u8(uint8x8_t a) {
   return vdupq_lane_u8(a, 7);
 }
 
-// CHECK: test_vdupq_lane_u16
+// CHECK-LABEL: test_vdupq_lane_u16
 // CHECK: vdup.16 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x8_t test_vdupq_lane_u16(uint16x4_t a) {
   return vdupq_lane_u16(a, 3);
 }
 
-// CHECK: test_vdupq_lane_u32
+// CHECK-LABEL: test_vdupq_lane_u32
 // CHECK: vdup.32 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vdupq_lane_u32(uint32x2_t a) {
   return vdupq_lane_u32(a, 1);
 }
 
-// CHECK: test_vdupq_lane_s8
+// CHECK-LABEL: test_vdupq_lane_s8
 // CHECK: vdup.8 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int8x16_t test_vdupq_lane_s8(int8x8_t a) {
   return vdupq_lane_s8(a, 7);
 }
 
-// CHECK: test_vdupq_lane_s16
+// CHECK-LABEL: test_vdupq_lane_s16
 // CHECK: vdup.16 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vdupq_lane_s16(int16x4_t a) {
   return vdupq_lane_s16(a, 3);
 }
 
-// CHECK: test_vdupq_lane_s32
+// CHECK-LABEL: test_vdupq_lane_s32
 // CHECK: vdup.32 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vdupq_lane_s32(int32x2_t a) {
   return vdupq_lane_s32(a, 1);
 }
 
-// CHECK: test_vdupq_lane_p8
+// CHECK-LABEL: test_vdupq_lane_p8
 // CHECK: vdup.8 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 poly8x16_t test_vdupq_lane_p8(poly8x8_t a) {
   return vdupq_lane_p8(a, 7);
 }
 
-// CHECK: test_vdupq_lane_p16
+// CHECK-LABEL: test_vdupq_lane_p16
 // CHECK: vdup.16 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 poly16x8_t test_vdupq_lane_p16(poly16x4_t a) {
   return vdupq_lane_p16(a, 3);
 }
 
-// CHECK: test_vdupq_lane_f32
+// CHECK-LABEL: test_vdupq_lane_f32
 // CHECK: vdup.32 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x4_t test_vdupq_lane_f32(float32x2_t a) {
   return vdupq_lane_f32(a, 1);
 }
 
-// CHECK: test_vdup_lane_s64
+// CHECK-LABEL: test_vdup_lane_s64
 int64x1_t test_vdup_lane_s64(int64x1_t a) {
   return vdup_lane_s64(a, 0);
 }
 
-// CHECK: test_vdup_lane_u64
+// CHECK-LABEL: test_vdup_lane_u64
 uint64x1_t test_vdup_lane_u64(uint64x1_t a) {
   return vdup_lane_u64(a, 0);
 }
 
-// CHECK: test_vdupq_lane_s64
+// CHECK-LABEL: test_vdupq_lane_s64
 // CHECK: {{vmov|vdup}}
 int64x2_t test_vdupq_lane_s64(int64x1_t a) {
   return vdupq_lane_s64(a, 0);
 }
 
-// CHECK: test_vdupq_lane_u64
+// CHECK-LABEL: test_vdupq_lane_u64
 // CHECK: {{vmov|vdup}}
 uint64x2_t test_vdupq_lane_u64(uint64x1_t a) {
   return vdupq_lane_u64(a, 0);
 }
 
 
-// CHECK: test_vdup_n_u8
+// CHECK-LABEL: test_vdup_n_u8
 // CHECK: vmov 
 uint8x8_t test_vdup_n_u8(uint8_t a) {
   return vdup_n_u8(a);
 }
 
-// CHECK: test_vdup_n_u16
+// CHECK-LABEL: test_vdup_n_u16
 // CHECK: vmov 
 uint16x4_t test_vdup_n_u16(uint16_t a) {
   return vdup_n_u16(a);
 }
 
-// CHECK: test_vdup_n_u32
+// CHECK-LABEL: test_vdup_n_u32
 // CHECK: vmov 
 uint32x2_t test_vdup_n_u32(uint32_t a) {
   return vdup_n_u32(a);
 }
 
-// CHECK: test_vdup_n_s8
+// CHECK-LABEL: test_vdup_n_s8
 // CHECK: vmov 
 int8x8_t test_vdup_n_s8(int8_t a) {
   return vdup_n_s8(a);
 }
 
-// CHECK: test_vdup_n_s16
+// CHECK-LABEL: test_vdup_n_s16
 // CHECK: vmov 
 int16x4_t test_vdup_n_s16(int16_t a) {
   return vdup_n_s16(a);
 }
 
-// CHECK: test_vdup_n_s32
+// CHECK-LABEL: test_vdup_n_s32
 // CHECK: vmov 
 int32x2_t test_vdup_n_s32(int32_t a) {
   return vdup_n_s32(a);
 }
 
-// CHECK: test_vdup_n_p8
+// CHECK-LABEL: test_vdup_n_p8
 // CHECK: vmov 
 poly8x8_t test_vdup_n_p8(poly8_t a) {
   return vdup_n_p8(a);
 }
 
-// CHECK: test_vdup_n_p16
+// CHECK-LABEL: test_vdup_n_p16
 // CHECK: vmov 
 poly16x4_t test_vdup_n_p16(poly16_t a) {
   return vdup_n_p16(a);
 }
 
-// CHECK: test_vdup_n_f16
+// CHECK-LABEL: test_vdup_n_f16
 // CHECK: vld1.16 {{{d[0-9]+\[\]}}}
 float16x4_t test_vdup_n_f16(float16_t *a) {
   return vdup_n_f16(*a);
 }
 
-// CHECK: test_vdup_n_f32
+// CHECK-LABEL: test_vdup_n_f32
 // CHECK: vmov 
 float32x2_t test_vdup_n_f32(float32_t a) {
   return vdup_n_f32(a);
 }
 
-// CHECK: test_vdupq_n_u8
+// CHECK-LABEL: test_vdupq_n_u8
 // CHECK: vmov 
 uint8x16_t test_vdupq_n_u8(uint8_t a) {
   return vdupq_n_u8(a);
 }
 
-// CHECK: test_vdupq_n_u16
+// CHECK-LABEL: test_vdupq_n_u16
 // CHECK: vmov 
 uint16x8_t test_vdupq_n_u16(uint16_t a) {
   return vdupq_n_u16(a);
 }
 
-// CHECK: test_vdupq_n_u32
+// CHECK-LABEL: test_vdupq_n_u32
 // CHECK: vmov 
 uint32x4_t test_vdupq_n_u32(uint32_t a) {
   return vdupq_n_u32(a);
 }
 
-// CHECK: test_vdupq_n_s8
+// CHECK-LABEL: test_vdupq_n_s8
 // CHECK: vmov 
 int8x16_t test_vdupq_n_s8(int8_t a) {
   return vdupq_n_s8(a);
 }
 
-// CHECK: test_vdupq_n_s16
+// CHECK-LABEL: test_vdupq_n_s16
 // CHECK: vmov 
 int16x8_t test_vdupq_n_s16(int16_t a) {
   return vdupq_n_s16(a);
 }
 
-// CHECK: test_vdupq_n_s32
+// CHECK-LABEL: test_vdupq_n_s32
 // CHECK: vmov 
 int32x4_t test_vdupq_n_s32(int32_t a) {
   return vdupq_n_s32(a);
 }
 
-// CHECK: test_vdupq_n_p8
+// CHECK-LABEL: test_vdupq_n_p8
 // CHECK: vmov 
 poly8x16_t test_vdupq_n_p8(poly8_t a) {
   return vdupq_n_p8(a);
 }
 
-// CHECK: test_vdupq_n_p16
+// CHECK-LABEL: test_vdupq_n_p16
 // CHECK: vmov 
 poly16x8_t test_vdupq_n_p16(poly16_t a) {
   return vdupq_n_p16(a);
 }
 
-// CHECK: test_vdupq_n_f16
+// CHECK-LABEL: test_vdupq_n_f16
 // CHECK: vld1.16 {{{d[0-9]+\[\], d[0-9]+\[\]}}}
 float16x8_t test_vdupq_n_f16(float16_t *a) {
   return vdupq_n_f16(*a);
 }
 
-// CHECK: test_vdupq_n_f32
+// CHECK-LABEL: test_vdupq_n_f32
 // CHECK: vmov 
 float32x4_t test_vdupq_n_f32(float32_t a) {
   return vdupq_n_f32(a);
 }
 
-// CHECK: test_vdup_n_s64
+// CHECK-LABEL: test_vdup_n_s64
 // CHECK: vmov 
 int64x1_t test_vdup_n_s64(int64_t a) {
   return vdup_n_s64(a);
 }
 
-// CHECK: test_vdup_n_u64
+// CHECK-LABEL: test_vdup_n_u64
 // CHECK: vmov 
 uint64x1_t test_vdup_n_u64(uint64_t a) {
   return vdup_n_u64(a);
 }
 
-// CHECK: test_vdupq_n_s64
+// CHECK-LABEL: test_vdupq_n_s64
 // CHECK: vmov 
 int64x2_t test_vdupq_n_s64(int64_t a) {
   return vdupq_n_s64(a);
 }
 
-// CHECK: test_vdupq_n_u64
+// CHECK-LABEL: test_vdupq_n_u64
 // CHECK: vmov 
 uint64x2_t test_vdupq_n_u64(uint64_t a) {
   return vdupq_n_u64(a);
 }
 
 
-// CHECK: test_veor_s8
+// CHECK-LABEL: test_veor_s8
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_veor_s8(int8x8_t a, int8x8_t b) {
   return veor_s8(a, b);
 }
 
-// CHECK: test_veor_s16
+// CHECK-LABEL: test_veor_s16
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_veor_s16(int16x4_t a, int16x4_t b) {
   return veor_s16(a, b);
 }
 
-// CHECK: test_veor_s32
+// CHECK-LABEL: test_veor_s32
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_veor_s32(int32x2_t a, int32x2_t b) {
   return veor_s32(a, b);
 }
 
-// CHECK: test_veor_s64
+// CHECK-LABEL: test_veor_s64
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_veor_s64(int64x1_t a, int64x1_t b) {
   return veor_s64(a, b);
 }
 
-// CHECK: test_veor_u8
+// CHECK-LABEL: test_veor_u8
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_veor_u8(uint8x8_t a, uint8x8_t b) {
   return veor_u8(a, b);
 }
 
-// CHECK: test_veor_u16
+// CHECK-LABEL: test_veor_u16
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_veor_u16(uint16x4_t a, uint16x4_t b) {
   return veor_u16(a, b);
 }
 
-// CHECK: test_veor_u32
+// CHECK-LABEL: test_veor_u32
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_veor_u32(uint32x2_t a, uint32x2_t b) {
   return veor_u32(a, b);
 }
 
-// CHECK: test_veor_u64
+// CHECK-LABEL: test_veor_u64
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_veor_u64(uint64x1_t a, uint64x1_t b) {
   return veor_u64(a, b);
 }
 
-// CHECK: test_veorq_s8
+// CHECK-LABEL: test_veorq_s8
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_veorq_s8(int8x16_t a, int8x16_t b) {
   return veorq_s8(a, b);
 }
 
-// CHECK: test_veorq_s16
+// CHECK-LABEL: test_veorq_s16
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_veorq_s16(int16x8_t a, int16x8_t b) {
   return veorq_s16(a, b);
 }
 
-// CHECK: test_veorq_s32
+// CHECK-LABEL: test_veorq_s32
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_veorq_s32(int32x4_t a, int32x4_t b) {
   return veorq_s32(a, b);
 }
 
-// CHECK: test_veorq_s64
+// CHECK-LABEL: test_veorq_s64
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_veorq_s64(int64x2_t a, int64x2_t b) {
   return veorq_s64(a, b);
 }
 
-// CHECK: test_veorq_u8
+// CHECK-LABEL: test_veorq_u8
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_veorq_u8(uint8x16_t a, uint8x16_t b) {
   return veorq_u8(a, b);
 }
 
-// CHECK: test_veorq_u16
+// CHECK-LABEL: test_veorq_u16
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_veorq_u16(uint16x8_t a, uint16x8_t b) {
   return veorq_u16(a, b);
 }
 
-// CHECK: test_veorq_u32
+// CHECK-LABEL: test_veorq_u32
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_veorq_u32(uint32x4_t a, uint32x4_t b) {
   return veorq_u32(a, b);
 }
 
-// CHECK: test_veorq_u64
+// CHECK-LABEL: test_veorq_u64
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_veorq_u64(uint64x2_t a, uint64x2_t b) {
   return veorq_u64(a, b);
 }
 
 
-// CHECK: test_vext_s8
+// CHECK-LABEL: test_vext_s8
 // CHECK: vext.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vext_s8(int8x8_t a, int8x8_t b) {
   return vext_s8(a, b, 7);
 }
 
-// CHECK: test_vext_u8
+// CHECK-LABEL: test_vext_u8
 // CHECK: vext.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vext_u8(uint8x8_t a, uint8x8_t b) {
   return vext_u8(a, b, 7);
 }
 
-// CHECK: test_vext_p8
+// CHECK-LABEL: test_vext_p8
 // CHECK: vext.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly8x8_t test_vext_p8(poly8x8_t a, poly8x8_t b) {
   return vext_p8(a, b, 7);
 }
 
-// CHECK: test_vext_s16
+// CHECK-LABEL: test_vext_s16
 // CHECK: vext.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vext_s16(int16x4_t a, int16x4_t b) {
   return vext_s16(a, b, 3);
 }
 
-// CHECK: test_vext_u16
+// CHECK-LABEL: test_vext_u16
 // CHECK: vext.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vext_u16(uint16x4_t a, uint16x4_t b) {
   return vext_u16(a, b, 3);
 }
 
-// CHECK: test_vext_p16
+// CHECK-LABEL: test_vext_p16
 // CHECK: vext.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly16x4_t test_vext_p16(poly16x4_t a, poly16x4_t b) {
   return vext_p16(a, b, 3);
 }
 
-// CHECK: test_vext_s32
+// CHECK-LABEL: test_vext_s32
 // CHECK: vext.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vext_s32(int32x2_t a, int32x2_t b) {
   return vext_s32(a, b, 1);
 }
 
-// CHECK: test_vext_u32
+// CHECK-LABEL: test_vext_u32
 // CHECK: vext.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vext_u32(uint32x2_t a, uint32x2_t b) {
   return vext_u32(a, b, 1);
 }
 
-// CHECK: test_vext_s64
+// CHECK-LABEL: test_vext_s64
 int64x1_t test_vext_s64(int64x1_t a, int64x1_t b) {
   return vext_s64(a, b, 0);
 }
 
-// CHECK: test_vext_u64
+// CHECK-LABEL: test_vext_u64
 uint64x1_t test_vext_u64(uint64x1_t a, uint64x1_t b) {
   return vext_u64(a, b, 0);
 }
 
-// CHECK: test_vext_f32
+// CHECK-LABEL: test_vext_f32
 // CHECK: vext.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 float32x2_t test_vext_f32(float32x2_t a, float32x2_t b) {
   return vext_f32(a, b, 1);
 }
 
-// CHECK: test_vextq_s8
+// CHECK-LABEL: test_vextq_s8
 // CHECK: vext.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vextq_s8(int8x16_t a, int8x16_t b) {
   return vextq_s8(a, b, 15);
 }
 
-// CHECK: test_vextq_u8
+// CHECK-LABEL: test_vextq_u8
 // CHECK: vext.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vextq_u8(uint8x16_t a, uint8x16_t b) {
   return vextq_u8(a, b, 15);
 }
 
-// CHECK: test_vextq_p8
+// CHECK-LABEL: test_vextq_p8
 // CHECK: vext.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly8x16_t test_vextq_p8(poly8x16_t a, poly8x16_t b) {
   return vextq_p8(a, b, 15);
 }
 
-// CHECK: test_vextq_s16
+// CHECK-LABEL: test_vextq_s16
 // CHECK: vext.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vextq_s16(int16x8_t a, int16x8_t b) {
   return vextq_s16(a, b, 7);
 }
 
-// CHECK: test_vextq_u16
+// CHECK-LABEL: test_vextq_u16
 // CHECK: vext.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vextq_u16(uint16x8_t a, uint16x8_t b) {
   return vextq_u16(a, b, 7);
 }
 
-// CHECK: test_vextq_p16
+// CHECK-LABEL: test_vextq_p16
 // CHECK: vext.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly16x8_t test_vextq_p16(poly16x8_t a, poly16x8_t b) {
   return vextq_p16(a, b, 7);
 }
 
-// CHECK: test_vextq_s32
+// CHECK-LABEL: test_vextq_s32
 // CHECK: vext.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vextq_s32(int32x4_t a, int32x4_t b) {
   return vextq_s32(a, b, 3);
 }
 
-// CHECK: test_vextq_u32
+// CHECK-LABEL: test_vextq_u32
 // CHECK: vext.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vextq_u32(uint32x4_t a, uint32x4_t b) {
   return vextq_u32(a, b, 3);
 }
 
-// CHECK: test_vextq_s64
+// CHECK-LABEL: test_vextq_s64
 // CHECK: {{vmov|vdup}}
 int64x2_t test_vextq_s64(int64x2_t a, int64x2_t b) {
   return vextq_s64(a, b, 1);
 }
 
-// CHECK: test_vextq_u64
+// CHECK-LABEL: test_vextq_u64
 // CHECK: {{vmov|vdup}}
 uint64x2_t test_vextq_u64(uint64x2_t a, uint64x2_t b) {
   return vextq_u64(a, b, 1);
 }
 
-// CHECK: test_vextq_f32
+// CHECK-LABEL: test_vextq_f32
 // CHECK: vext.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 float32x4_t test_vextq_f32(float32x4_t a, float32x4_t b) {
   return vextq_f32(a, b, 3);
 }
 
 
-// CHECK: test_vfma_f32
+// CHECK-LABEL: test_vfma_f32
 // CHECK: vfma.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vfma_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vfma_f32(a, b, c);
 }
 
-// CHECK: test_vfmaq_f32
+// CHECK-LABEL: test_vfmaq_f32
 // CHECK: vfma.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vfmaq_f32(float32x4_t a, float32x4_t b, float32x4_t c) {
   return vfmaq_f32(a, b, c);
 }
 
 
-// CHECK: test_vget_high_s8
+// CHECK-LABEL: test_vget_high_s8
 int8x8_t test_vget_high_s8(int8x16_t a) {
   return vget_high_s8(a);
 }
 
-// CHECK: test_vget_high_s16
+// CHECK-LABEL: test_vget_high_s16
 int16x4_t test_vget_high_s16(int16x8_t a) {
   return vget_high_s16(a);
 }
 
-// CHECK: test_vget_high_s32
+// CHECK-LABEL: test_vget_high_s32
 int32x2_t test_vget_high_s32(int32x4_t a) {
   return vget_high_s32(a);
 }
 
-// CHECK: test_vget_high_s64
+// CHECK-LABEL: test_vget_high_s64
 int64x1_t test_vget_high_s64(int64x2_t a) {
   return vget_high_s64(a);
 }
 
-// CHECK: test_vget_high_f16
+// CHECK-LABEL: test_vget_high_f16
 float16x4_t test_vget_high_f16(float16x8_t a) {
   return vget_high_f16(a);
 }
 
-// CHECK: test_vget_high_f32
+// CHECK-LABEL: test_vget_high_f32
 float32x2_t test_vget_high_f32(float32x4_t a) {
   return vget_high_f32(a);
 }
 
-// CHECK: test_vget_high_u8
+// CHECK-LABEL: test_vget_high_u8
 uint8x8_t test_vget_high_u8(uint8x16_t a) {
   return vget_high_u8(a);
 }
 
-// CHECK: test_vget_high_u16
+// CHECK-LABEL: test_vget_high_u16
 uint16x4_t test_vget_high_u16(uint16x8_t a) {
   return vget_high_u16(a);
 }
 
-// CHECK: test_vget_high_u32
+// CHECK-LABEL: test_vget_high_u32
 uint32x2_t test_vget_high_u32(uint32x4_t a) {
   return vget_high_u32(a);
 }
 
-// CHECK: test_vget_high_u64
+// CHECK-LABEL: test_vget_high_u64
 uint64x1_t test_vget_high_u64(uint64x2_t a) {
   return vget_high_u64(a);
 }
 
-// CHECK: test_vget_high_p8
+// CHECK-LABEL: test_vget_high_p8
 poly8x8_t test_vget_high_p8(poly8x16_t a) {
   return vget_high_p8(a);
 }
 
-// CHECK: test_vget_high_p16
+// CHECK-LABEL: test_vget_high_p16
 poly16x4_t test_vget_high_p16(poly16x8_t a) {
   return vget_high_p16(a);
 }
 
 
-// CHECK: test_vget_lane_u8
+// CHECK-LABEL: test_vget_lane_u8
 // CHECK: vmov 
 uint8_t test_vget_lane_u8(uint8x8_t a) {
   return vget_lane_u8(a, 7);
 }
 
-// CHECK: test_vget_lane_u16
+// CHECK-LABEL: test_vget_lane_u16
 // CHECK: vmov 
 uint16_t test_vget_lane_u16(uint16x4_t a) {
   return vget_lane_u16(a, 3);
 }
 
-// CHECK: test_vget_lane_u32
+// CHECK-LABEL: test_vget_lane_u32
 // CHECK: vmov 
 uint32_t test_vget_lane_u32(uint32x2_t a) {
   return vget_lane_u32(a, 1);
 }
 
-// CHECK: test_vget_lane_s8
+// CHECK-LABEL: test_vget_lane_s8
 // CHECK: vmov 
 int8_t test_vget_lane_s8(int8x8_t a) {
   return vget_lane_s8(a, 7);
 }
 
-// CHECK: test_vget_lane_s16
+// CHECK-LABEL: test_vget_lane_s16
 // CHECK: vmov 
 int16_t test_vget_lane_s16(int16x4_t a) {
   return vget_lane_s16(a, 3);
 }
 
-// CHECK: test_vget_lane_s32
+// CHECK-LABEL: test_vget_lane_s32
 // CHECK: vmov 
 int32_t test_vget_lane_s32(int32x2_t a) {
   return vget_lane_s32(a, 1);
 }
 
-// CHECK: test_vget_lane_p8
+// CHECK-LABEL: test_vget_lane_p8
 // CHECK: vmov 
 poly8_t test_vget_lane_p8(poly8x8_t a) {
   return vget_lane_p8(a, 7);
 }
 
-// CHECK: test_vget_lane_p16
+// CHECK-LABEL: test_vget_lane_p16
 // CHECK: vmov 
 poly16_t test_vget_lane_p16(poly16x4_t a) {
   return vget_lane_p16(a, 3);
 }
 
-// CHECK: test_vget_lane_f32
+// CHECK-LABEL: test_vget_lane_f32
 // CHECK: vmov 
 float32_t test_vget_lane_f32(float32x2_t a) {
   return vget_lane_f32(a, 1);
 }
 
-// CHECK: test_vgetq_lane_u8
+// CHECK-LABEL: test_vgetq_lane_u8
 // CHECK: vmov 
 uint8_t test_vgetq_lane_u8(uint8x16_t a) {
   return vgetq_lane_u8(a, 15);
 }
 
-// CHECK: test_vgetq_lane_u16
+// CHECK-LABEL: test_vgetq_lane_u16
 // CHECK: vmov 
 uint16_t test_vgetq_lane_u16(uint16x8_t a) {
   return vgetq_lane_u16(a, 7);
 }
 
-// CHECK: test_vgetq_lane_u32
+// CHECK-LABEL: test_vgetq_lane_u32
 // CHECK: vmov 
 uint32_t test_vgetq_lane_u32(uint32x4_t a) {
   return vgetq_lane_u32(a, 3);
 }
 
-// CHECK: test_vgetq_lane_s8
+// CHECK-LABEL: test_vgetq_lane_s8
 // CHECK: vmov 
 int8_t test_vgetq_lane_s8(int8x16_t a) {
   return vgetq_lane_s8(a, 15);
 }
 
-// CHECK: test_vgetq_lane_s16
+// CHECK-LABEL: test_vgetq_lane_s16
 // CHECK: vmov 
 int16_t test_vgetq_lane_s16(int16x8_t a) {
   return vgetq_lane_s16(a, 7);
 }
 
-// CHECK: test_vgetq_lane_s32
+// CHECK-LABEL: test_vgetq_lane_s32
 // CHECK: vmov 
 int32_t test_vgetq_lane_s32(int32x4_t a) {
   return vgetq_lane_s32(a, 3);
 }
 
-// CHECK: test_vgetq_lane_p8
+// CHECK-LABEL: test_vgetq_lane_p8
 // CHECK: vmov 
 poly8_t test_vgetq_lane_p8(poly8x16_t a) {
   return vgetq_lane_p8(a, 15);
 }
 
-// CHECK: test_vgetq_lane_p16
+// CHECK-LABEL: test_vgetq_lane_p16
 // CHECK: vmov 
 poly16_t test_vgetq_lane_p16(poly16x8_t a) {
   return vgetq_lane_p16(a, 7);
 }
 
-// CHECK: test_vgetq_lane_f32
+// CHECK-LABEL: test_vgetq_lane_f32
 // CHECK: vmov 
 float32_t test_vgetq_lane_f32(float32x4_t a) {
   return vgetq_lane_f32(a, 3);
 }
 
-// CHECK: test_vget_lane_s64
+// CHECK-LABEL: test_vget_lane_s64
 // CHECK: vmov 
 int64_t test_vget_lane_s64(int64x1_t a) {
   return vget_lane_s64(a, 0);
 }
 
-// CHECK: test_vget_lane_u64
+// CHECK-LABEL: test_vget_lane_u64
 // CHECK: vmov 
 uint64_t test_vget_lane_u64(uint64x1_t a) {
   return vget_lane_u64(a, 0);
 }
 
-// CHECK: test_vgetq_lane_s64
+// CHECK-LABEL: test_vgetq_lane_s64
 // CHECK: vmov 
 int64_t test_vgetq_lane_s64(int64x2_t a) {
   return vgetq_lane_s64(a, 1);
 }
 
-// CHECK: test_vgetq_lane_u64
+// CHECK-LABEL: test_vgetq_lane_u64
 // CHECK: vmov 
 uint64_t test_vgetq_lane_u64(uint64x2_t a) {
   return vgetq_lane_u64(a, 1);
 }
 
 
-// CHECK: test_vget_low_s8
+// CHECK-LABEL: test_vget_low_s8
 int8x8_t test_vget_low_s8(int8x16_t a) {
   return vget_low_s8(a);
 }
 
-// CHECK: test_vget_low_s16
+// CHECK-LABEL: test_vget_low_s16
 int16x4_t test_vget_low_s16(int16x8_t a) {
   return vget_low_s16(a);
 }
 
-// CHECK: test_vget_low_s32
+// CHECK-LABEL: test_vget_low_s32
 int32x2_t test_vget_low_s32(int32x4_t a) {
   return vget_low_s32(a);
 }
 
-// CHECK: test_vget_low_s64
+// CHECK-LABEL: test_vget_low_s64
 int64x1_t test_vget_low_s64(int64x2_t a) {
   return vget_low_s64(a);
 }
 
-// CHECK: test_vget_low_f16
+// CHECK-LABEL: test_vget_low_f16
 float16x4_t test_vget_low_f16(float16x8_t a) {
   return vget_low_f16(a);
 }
 
-// CHECK: test_vget_low_f32
+// CHECK-LABEL: test_vget_low_f32
 float32x2_t test_vget_low_f32(float32x4_t a) {
   return vget_low_f32(a);
 }
 
-// CHECK: test_vget_low_u8
+// CHECK-LABEL: test_vget_low_u8
 uint8x8_t test_vget_low_u8(uint8x16_t a) {
   return vget_low_u8(a);
 }
 
-// CHECK: test_vget_low_u16
+// CHECK-LABEL: test_vget_low_u16
 uint16x4_t test_vget_low_u16(uint16x8_t a) {
   return vget_low_u16(a);
 }
 
-// CHECK: test_vget_low_u32
+// CHECK-LABEL: test_vget_low_u32
 uint32x2_t test_vget_low_u32(uint32x4_t a) {
   return vget_low_u32(a);
 }
 
-// CHECK: test_vget_low_u64
+// CHECK-LABEL: test_vget_low_u64
 uint64x1_t test_vget_low_u64(uint64x2_t a) {
   return vget_low_u64(a);
 }
 
-// CHECK: test_vget_low_p8
+// CHECK-LABEL: test_vget_low_p8
 poly8x8_t test_vget_low_p8(poly8x16_t a) {
   return vget_low_p8(a);
 }
 
-// CHECK: test_vget_low_p16
+// CHECK-LABEL: test_vget_low_p16
 poly16x4_t test_vget_low_p16(poly16x8_t a) {
   return vget_low_p16(a);
 }
 
 
-// CHECK: test_vhadd_s8
+// CHECK-LABEL: test_vhadd_s8
 // CHECK: vhadd.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vhadd_s8(int8x8_t a, int8x8_t b) {
   return vhadd_s8(a, b);
 }
 
-// CHECK: test_vhadd_s16
+// CHECK-LABEL: test_vhadd_s16
 // CHECK: vhadd.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vhadd_s16(int16x4_t a, int16x4_t b) {
   return vhadd_s16(a, b);
 }
 
-// CHECK: test_vhadd_s32
+// CHECK-LABEL: test_vhadd_s32
 // CHECK: vhadd.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vhadd_s32(int32x2_t a, int32x2_t b) {
   return vhadd_s32(a, b);
 }
 
-// CHECK: test_vhadd_u8
+// CHECK-LABEL: test_vhadd_u8
 // CHECK: vhadd.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vhadd_u8(uint8x8_t a, uint8x8_t b) {
   return vhadd_u8(a, b);
 }
 
-// CHECK: test_vhadd_u16
+// CHECK-LABEL: test_vhadd_u16
 // CHECK: vhadd.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vhadd_u16(uint16x4_t a, uint16x4_t b) {
   return vhadd_u16(a, b);
 }
 
-// CHECK: test_vhadd_u32
+// CHECK-LABEL: test_vhadd_u32
 // CHECK: vhadd.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vhadd_u32(uint32x2_t a, uint32x2_t b) {
   return vhadd_u32(a, b);
 }
 
-// CHECK: test_vhaddq_s8
+// CHECK-LABEL: test_vhaddq_s8
 // CHECK: vhadd.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vhaddq_s8(int8x16_t a, int8x16_t b) {
   return vhaddq_s8(a, b);
 }
 
-// CHECK: test_vhaddq_s16
+// CHECK-LABEL: test_vhaddq_s16
 // CHECK: vhadd.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vhaddq_s16(int16x8_t a, int16x8_t b) {
   return vhaddq_s16(a, b);
 }
 
-// CHECK: test_vhaddq_s32
+// CHECK-LABEL: test_vhaddq_s32
 // CHECK: vhadd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vhaddq_s32(int32x4_t a, int32x4_t b) {
   return vhaddq_s32(a, b);
 }
 
-// CHECK: test_vhaddq_u8
+// CHECK-LABEL: test_vhaddq_u8
 // CHECK: vhadd.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vhaddq_u8(uint8x16_t a, uint8x16_t b) {
   return vhaddq_u8(a, b);
 }
 
-// CHECK: test_vhaddq_u16
+// CHECK-LABEL: test_vhaddq_u16
 // CHECK: vhadd.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vhaddq_u16(uint16x8_t a, uint16x8_t b) {
   return vhaddq_u16(a, b);
 }
 
-// CHECK: test_vhaddq_u32
+// CHECK-LABEL: test_vhaddq_u32
 // CHECK: vhadd.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vhaddq_u32(uint32x4_t a, uint32x4_t b) {
   return vhaddq_u32(a, b);
 }
 
 
-// CHECK: test_vhsub_s8
+// CHECK-LABEL: test_vhsub_s8
 // CHECK: vhsub.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vhsub_s8(int8x8_t a, int8x8_t b) {
   return vhsub_s8(a, b);
 }
 
-// CHECK: test_vhsub_s16
+// CHECK-LABEL: test_vhsub_s16
 // CHECK: vhsub.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vhsub_s16(int16x4_t a, int16x4_t b) {
   return vhsub_s16(a, b);
 }
 
-// CHECK: test_vhsub_s32
+// CHECK-LABEL: test_vhsub_s32
 // CHECK: vhsub.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vhsub_s32(int32x2_t a, int32x2_t b) {
   return vhsub_s32(a, b);
 }
 
-// CHECK: test_vhsub_u8
+// CHECK-LABEL: test_vhsub_u8
 // CHECK: vhsub.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vhsub_u8(uint8x8_t a, uint8x8_t b) {
   return vhsub_u8(a, b);
 }
 
-// CHECK: test_vhsub_u16
+// CHECK-LABEL: test_vhsub_u16
 // CHECK: vhsub.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vhsub_u16(uint16x4_t a, uint16x4_t b) {
   return vhsub_u16(a, b);
 }
 
-// CHECK: test_vhsub_u32
+// CHECK-LABEL: test_vhsub_u32
 // CHECK: vhsub.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vhsub_u32(uint32x2_t a, uint32x2_t b) {
   return vhsub_u32(a, b);
 }
 
-// CHECK: test_vhsubq_s8
+// CHECK-LABEL: test_vhsubq_s8
 // CHECK: vhsub.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vhsubq_s8(int8x16_t a, int8x16_t b) {
   return vhsubq_s8(a, b);
 }
 
-// CHECK: test_vhsubq_s16
+// CHECK-LABEL: test_vhsubq_s16
 // CHECK: vhsub.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vhsubq_s16(int16x8_t a, int16x8_t b) {
   return vhsubq_s16(a, b);
 }
 
-// CHECK: test_vhsubq_s32
+// CHECK-LABEL: test_vhsubq_s32
 // CHECK: vhsub.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vhsubq_s32(int32x4_t a, int32x4_t b) {
   return vhsubq_s32(a, b);
 }
 
-// CHECK: test_vhsubq_u8
+// CHECK-LABEL: test_vhsubq_u8
 // CHECK: vhsub.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vhsubq_u8(uint8x16_t a, uint8x16_t b) {
   return vhsubq_u8(a, b);
 }
 
-// CHECK: test_vhsubq_u16
+// CHECK-LABEL: test_vhsubq_u16
 // CHECK: vhsub.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vhsubq_u16(uint16x8_t a, uint16x8_t b) {
   return vhsubq_u16(a, b);
 }
 
-// CHECK: test_vhsubq_u32
+// CHECK-LABEL: test_vhsubq_u32
 // CHECK: vhsub.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vhsubq_u32(uint32x4_t a, uint32x4_t b) {
   return vhsubq_u32(a, b);
 }
 
 
-// CHECK: test_vld1q_u8
+// CHECK-LABEL: test_vld1q_u8
 // CHECK: vld1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x16_t test_vld1q_u8(uint8_t const * a) {
   return vld1q_u8(a);
 }
 
-// CHECK: test_vld1q_u16
+// CHECK-LABEL: test_vld1q_u16
 // CHECK: vld1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x8_t test_vld1q_u16(uint16_t const * a) {
   return vld1q_u16(a);
 }
 
-// CHECK: test_vld1q_u32
+// CHECK-LABEL: test_vld1q_u32
 // CHECK: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x4_t test_vld1q_u32(uint32_t const * a) {
   return vld1q_u32(a);
 }
 
-// CHECK: test_vld1q_u64
-// CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vld1q_u64
+// CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 uint64x2_t test_vld1q_u64(uint64_t const * a) {
   return vld1q_u64(a);
 }
 
-// CHECK: test_vld1q_s8
+// CHECK-LABEL: test_vld1q_s8
 // CHECK: vld1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x16_t test_vld1q_s8(int8_t const * a) {
   return vld1q_s8(a);
 }
 
-// CHECK: test_vld1q_s16
+// CHECK-LABEL: test_vld1q_s16
 // CHECK: vld1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x8_t test_vld1q_s16(int16_t const * a) {
   return vld1q_s16(a);
 }
 
-// CHECK: test_vld1q_s32
+// CHECK-LABEL: test_vld1q_s32
 // CHECK: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x4_t test_vld1q_s32(int32_t const * a) {
   return vld1q_s32(a);
 }
 
-// CHECK: test_vld1q_s64
-// CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vld1q_s64
+// CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 int64x2_t test_vld1q_s64(int64_t const * a) {
   return vld1q_s64(a);
 }
 
-// CHECK: test_vld1q_f16
+// CHECK-LABEL: test_vld1q_f16
 // CHECK: vld1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x8_t test_vld1q_f16(float16_t const * a) {
   return vld1q_f16(a);
 }
 
-// CHECK: test_vld1q_f32
+// CHECK-LABEL: test_vld1q_f32
 // CHECK: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x4_t test_vld1q_f32(float32_t const * a) {
   return vld1q_f32(a);
 }
 
-// CHECK: test_vld1q_p8
+// CHECK-LABEL: test_vld1q_p8
 // CHECK: vld1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x16_t test_vld1q_p8(poly8_t const * a) {
   return vld1q_p8(a);
 }
 
-// CHECK: test_vld1q_p16
+// CHECK-LABEL: test_vld1q_p16
 // CHECK: vld1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x8_t test_vld1q_p16(poly16_t const * a) {
   return vld1q_p16(a);
 }
 
-// CHECK: test_vld1_u8
+// CHECK-LABEL: test_vld1_u8
 // CHECK: vld1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x8_t test_vld1_u8(uint8_t const * a) {
   return vld1_u8(a);
 }
 
-// CHECK: test_vld1_u16
+// CHECK-LABEL: test_vld1_u16
 // CHECK: vld1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x4_t test_vld1_u16(uint16_t const * a) {
   return vld1_u16(a);
 }
 
-// CHECK: test_vld1_u32
+// CHECK-LABEL: test_vld1_u32
 // CHECK: vld1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x2_t test_vld1_u32(uint32_t const * a) {
   return vld1_u32(a);
 }
 
-// CHECK: test_vld1_u64
-// CHECK: vld1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vld1_u64
+// CHECK: vld1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 uint64x1_t test_vld1_u64(uint64_t const * a) {
   return vld1_u64(a);
 }
 
-// CHECK: test_vld1_s8
+// CHECK-LABEL: test_vld1_s8
 // CHECK: vld1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x8_t test_vld1_s8(int8_t const * a) {
   return vld1_s8(a);
 }
 
-// CHECK: test_vld1_s16
+// CHECK-LABEL: test_vld1_s16
 // CHECK: vld1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x4_t test_vld1_s16(int16_t const * a) {
   return vld1_s16(a);
 }
 
-// CHECK: test_vld1_s32
+// CHECK-LABEL: test_vld1_s32
 // CHECK: vld1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x2_t test_vld1_s32(int32_t const * a) {
   return vld1_s32(a);
 }
 
-// CHECK: test_vld1_s64
-// CHECK: vld1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vld1_s64
+// CHECK: vld1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 int64x1_t test_vld1_s64(int64_t const * a) {
   return vld1_s64(a);
 }
 
-// CHECK: test_vld1_f16
+// CHECK-LABEL: test_vld1_f16
 // CHECK: vld1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x4_t test_vld1_f16(float16_t const * a) {
   return vld1_f16(a);
 }
 
-// CHECK: test_vld1_f32
+// CHECK-LABEL: test_vld1_f32
 // CHECK: vld1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x2_t test_vld1_f32(float32_t const * a) {
   return vld1_f32(a);
 }
 
-// CHECK: test_vld1_p8
+// CHECK-LABEL: test_vld1_p8
 // CHECK: vld1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x8_t test_vld1_p8(poly8_t const * a) {
   return vld1_p8(a);
 }
 
-// CHECK: test_vld1_p16
+// CHECK-LABEL: test_vld1_p16
 // CHECK: vld1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x4_t test_vld1_p16(poly16_t const * a) {
   return vld1_p16(a);
 }
 
 
-// CHECK: test_vld1q_dup_u8
+// CHECK-LABEL: test_vld1q_dup_u8
 // CHECK: vld1.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x16_t test_vld1q_dup_u8(uint8_t const * a) {
   return vld1q_dup_u8(a);
 }
 
-// CHECK: test_vld1q_dup_u16
+// CHECK-LABEL: test_vld1q_dup_u16
 // CHECK: vld1.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 uint16x8_t test_vld1q_dup_u16(uint16_t const * a) {
   return vld1q_dup_u16(a);
 }
 
-// CHECK: test_vld1q_dup_u32
+// CHECK-LABEL: test_vld1q_dup_u32
 // CHECK: vld1.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 uint32x4_t test_vld1q_dup_u32(uint32_t const * a) {
   return vld1q_dup_u32(a);
 }
 
-// CHECK: test_vld1q_dup_u64
+// CHECK-LABEL: test_vld1q_dup_u64
 // CHECK: {{ldr|vldr|vmov}}
 uint64x2_t test_vld1q_dup_u64(uint64_t const * a) {
   return vld1q_dup_u64(a);
 }
 
-// CHECK: test_vld1q_dup_s8
+// CHECK-LABEL: test_vld1q_dup_s8
 // CHECK: vld1.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x16_t test_vld1q_dup_s8(int8_t const * a) {
   return vld1q_dup_s8(a);
 }
 
-// CHECK: test_vld1q_dup_s16
+// CHECK-LABEL: test_vld1q_dup_s16
 // CHECK: vld1.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 int16x8_t test_vld1q_dup_s16(int16_t const * a) {
   return vld1q_dup_s16(a);
 }
 
-// CHECK: test_vld1q_dup_s32
+// CHECK-LABEL: test_vld1q_dup_s32
 // CHECK: vld1.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 int32x4_t test_vld1q_dup_s32(int32_t const * a) {
   return vld1q_dup_s32(a);
 }
 
-// CHECK: test_vld1q_dup_s64
+// CHECK-LABEL: test_vld1q_dup_s64
 // CHECK: {{ldr|vldr|vmov}}
 int64x2_t test_vld1q_dup_s64(int64_t const * a) {
   return vld1q_dup_s64(a);
 }
 
-// CHECK: test_vld1q_dup_f16
+// CHECK-LABEL: test_vld1q_dup_f16
 // CHECK: vld1.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 float16x8_t test_vld1q_dup_f16(float16_t const * a) {
   return vld1q_dup_f16(a);
 }
 
-// CHECK: test_vld1q_dup_f32
+// CHECK-LABEL: test_vld1q_dup_f32
 // CHECK: vld1.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 float32x4_t test_vld1q_dup_f32(float32_t const * a) {
   return vld1q_dup_f32(a);
 }
 
-// CHECK: test_vld1q_dup_p8
+// CHECK-LABEL: test_vld1q_dup_p8
 // CHECK: vld1.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x16_t test_vld1q_dup_p8(poly8_t const * a) {
   return vld1q_dup_p8(a);
 }
 
-// CHECK: test_vld1q_dup_p16
+// CHECK-LABEL: test_vld1q_dup_p16
 // CHECK: vld1.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 poly16x8_t test_vld1q_dup_p16(poly16_t const * a) {
   return vld1q_dup_p16(a);
 }
 
-// CHECK: test_vld1_dup_u8
+// CHECK-LABEL: test_vld1_dup_u8
 // CHECK: vld1.8 {d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x8_t test_vld1_dup_u8(uint8_t const * a) {
   return vld1_dup_u8(a);
 }
 
-// CHECK: test_vld1_dup_u16
+// CHECK-LABEL: test_vld1_dup_u16
 // CHECK: vld1.16 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 uint16x4_t test_vld1_dup_u16(uint16_t const * a) {
   return vld1_dup_u16(a);
 }
 
-// CHECK: test_vld1_dup_u32
+// CHECK-LABEL: test_vld1_dup_u32
 // CHECK: vld1.32 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 uint32x2_t test_vld1_dup_u32(uint32_t const * a) {
   return vld1_dup_u32(a);
 }
 
-// CHECK: test_vld1_dup_u64
+// CHECK-LABEL: test_vld1_dup_u64
 // CHECK: {{ldr|vldr|vmov}}
 uint64x1_t test_vld1_dup_u64(uint64_t const * a) {
   return vld1_dup_u64(a);
 }
 
-// CHECK: test_vld1_dup_s8
+// CHECK-LABEL: test_vld1_dup_s8
 // CHECK: vld1.8 {d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x8_t test_vld1_dup_s8(int8_t const * a) {
   return vld1_dup_s8(a);
 }
 
-// CHECK: test_vld1_dup_s16
+// CHECK-LABEL: test_vld1_dup_s16
 // CHECK: vld1.16 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 int16x4_t test_vld1_dup_s16(int16_t const * a) {
   return vld1_dup_s16(a);
 }
 
-// CHECK: test_vld1_dup_s32
+// CHECK-LABEL: test_vld1_dup_s32
 // CHECK: vld1.32 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 int32x2_t test_vld1_dup_s32(int32_t const * a) {
   return vld1_dup_s32(a);
 }
 
-// CHECK: test_vld1_dup_s64
+// CHECK-LABEL: test_vld1_dup_s64
 // CHECK: {{ldr|vldr|vmov}}
 int64x1_t test_vld1_dup_s64(int64_t const * a) {
   return vld1_dup_s64(a);
 }
 
-// CHECK: test_vld1_dup_f16
+// CHECK-LABEL: test_vld1_dup_f16
 // CHECK: vld1.16 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 float16x4_t test_vld1_dup_f16(float16_t const * a) {
   return vld1_dup_f16(a);
 }
 
-// CHECK: test_vld1_dup_f32
+// CHECK-LABEL: test_vld1_dup_f32
 // CHECK: vld1.32 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 float32x2_t test_vld1_dup_f32(float32_t const * a) {
   return vld1_dup_f32(a);
 }
 
-// CHECK: test_vld1_dup_p8
+// CHECK-LABEL: test_vld1_dup_p8
 // CHECK: vld1.8 {d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x8_t test_vld1_dup_p8(poly8_t const * a) {
   return vld1_dup_p8(a);
 }
 
-// CHECK: test_vld1_dup_p16
+// CHECK-LABEL: test_vld1_dup_p16
 // CHECK: vld1.16 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 poly16x4_t test_vld1_dup_p16(poly16_t const * a) {
   return vld1_dup_p16(a);
 }
 
 
-// CHECK: test_vld1q_lane_u8
+// CHECK-LABEL: test_vld1q_lane_u8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x16_t test_vld1q_lane_u8(uint8_t const * a, uint8x16_t b) {
   return vld1q_lane_u8(a, b, 15);
 }
 
-// CHECK: test_vld1q_lane_u16
+// CHECK-LABEL: test_vld1q_lane_u16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 uint16x8_t test_vld1q_lane_u16(uint16_t const * a, uint16x8_t b) {
   return vld1q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vld1q_lane_u32
+// CHECK-LABEL: test_vld1q_lane_u32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 uint32x4_t test_vld1q_lane_u32(uint32_t const * a, uint32x4_t b) {
   return vld1q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vld1q_lane_u64
+// CHECK-LABEL: test_vld1q_lane_u64
 // CHECK: {{ldr|vldr|vmov}}
 uint64x2_t test_vld1q_lane_u64(uint64_t const * a, uint64x2_t b) {
   return vld1q_lane_u64(a, b, 1);
 }
 
-// CHECK: test_vld1q_lane_s8
+// CHECK-LABEL: test_vld1q_lane_s8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x16_t test_vld1q_lane_s8(int8_t const * a, int8x16_t b) {
   return vld1q_lane_s8(a, b, 15);
 }
 
-// CHECK: test_vld1q_lane_s16
+// CHECK-LABEL: test_vld1q_lane_s16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 int16x8_t test_vld1q_lane_s16(int16_t const * a, int16x8_t b) {
   return vld1q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vld1q_lane_s32
+// CHECK-LABEL: test_vld1q_lane_s32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 int32x4_t test_vld1q_lane_s32(int32_t const * a, int32x4_t b) {
   return vld1q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vld1q_lane_s64
+// CHECK-LABEL: test_vld1q_lane_s64
 // CHECK: {{ldr|vldr|vmov}}
 int64x2_t test_vld1q_lane_s64(int64_t const * a, int64x2_t b) {
   return vld1q_lane_s64(a, b, 1);
 }
 
-// CHECK: test_vld1q_lane_f16
+// CHECK-LABEL: test_vld1q_lane_f16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 float16x8_t test_vld1q_lane_f16(float16_t const * a, float16x8_t b) {
   return vld1q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vld1q_lane_f32
+// CHECK-LABEL: test_vld1q_lane_f32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 float32x4_t test_vld1q_lane_f32(float32_t const * a, float32x4_t b) {
   return vld1q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vld1q_lane_p8
+// CHECK-LABEL: test_vld1q_lane_p8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x16_t test_vld1q_lane_p8(poly8_t const * a, poly8x16_t b) {
   return vld1q_lane_p8(a, b, 15);
 }
 
-// CHECK: test_vld1q_lane_p16
+// CHECK-LABEL: test_vld1q_lane_p16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 poly16x8_t test_vld1q_lane_p16(poly16_t const * a, poly16x8_t b) {
   return vld1q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vld1_lane_u8
+// CHECK-LABEL: test_vld1_lane_u8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x8_t test_vld1_lane_u8(uint8_t const * a, uint8x8_t b) {
   return vld1_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vld1_lane_u16
+// CHECK-LABEL: test_vld1_lane_u16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 uint16x4_t test_vld1_lane_u16(uint16_t const * a, uint16x4_t b) {
   return vld1_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vld1_lane_u32
+// CHECK-LABEL: test_vld1_lane_u32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 uint32x2_t test_vld1_lane_u32(uint32_t const * a, uint32x2_t b) {
   return vld1_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vld1_lane_u64
+// CHECK-LABEL: test_vld1_lane_u64
 // CHECK: {{ldr|vldr|vmov}}
 uint64x1_t test_vld1_lane_u64(uint64_t const * a, uint64x1_t b) {
   return vld1_lane_u64(a, b, 0);
 }
 
-// CHECK: test_vld1_lane_s8
+// CHECK-LABEL: test_vld1_lane_s8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x8_t test_vld1_lane_s8(int8_t const * a, int8x8_t b) {
   return vld1_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vld1_lane_s16
+// CHECK-LABEL: test_vld1_lane_s16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 int16x4_t test_vld1_lane_s16(int16_t const * a, int16x4_t b) {
   return vld1_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vld1_lane_s32
+// CHECK-LABEL: test_vld1_lane_s32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 int32x2_t test_vld1_lane_s32(int32_t const * a, int32x2_t b) {
   return vld1_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vld1_lane_s64
+// CHECK-LABEL: test_vld1_lane_s64
 // CHECK: {{ldr|vldr|vmov}}
 int64x1_t test_vld1_lane_s64(int64_t const * a, int64x1_t b) {
   return vld1_lane_s64(a, b, 0);
 }
 
-// CHECK: test_vld1_lane_f16
+// CHECK-LABEL: test_vld1_lane_f16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 float16x4_t test_vld1_lane_f16(float16_t const * a, float16x4_t b) {
   return vld1_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vld1_lane_f32
+// CHECK-LABEL: test_vld1_lane_f32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 float32x2_t test_vld1_lane_f32(float32_t const * a, float32x2_t b) {
   return vld1_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vld1_lane_p8
+// CHECK-LABEL: test_vld1_lane_p8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x8_t test_vld1_lane_p8(poly8_t const * a, poly8x8_t b) {
   return vld1_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vld1_lane_p16
+// CHECK-LABEL: test_vld1_lane_p16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 poly16x4_t test_vld1_lane_p16(poly16_t const * a, poly16x4_t b) {
   return vld1_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vld2q_u8
+// CHECK-LABEL: test_vld2q_u8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x16x2_t test_vld2q_u8(uint8_t const * a) {
   return vld2q_u8(a);
 }
 
-// CHECK: test_vld2q_u16
+// CHECK-LABEL: test_vld2q_u16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x8x2_t test_vld2q_u16(uint16_t const * a) {
   return vld2q_u16(a);
 }
 
-// CHECK: test_vld2q_u32
+// CHECK-LABEL: test_vld2q_u32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x4x2_t test_vld2q_u32(uint32_t const * a) {
   return vld2q_u32(a);
 }
 
-// CHECK: test_vld2q_s8
+// CHECK-LABEL: test_vld2q_s8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x16x2_t test_vld2q_s8(int8_t const * a) {
   return vld2q_s8(a);
 }
 
-// CHECK: test_vld2q_s16
+// CHECK-LABEL: test_vld2q_s16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x8x2_t test_vld2q_s16(int16_t const * a) {
   return vld2q_s16(a);
 }
 
-// CHECK: test_vld2q_s32
+// CHECK-LABEL: test_vld2q_s32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x4x2_t test_vld2q_s32(int32_t const * a) {
   return vld2q_s32(a);
 }
 
-// CHECK: test_vld2q_f16
+// CHECK-LABEL: test_vld2q_f16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x8x2_t test_vld2q_f16(float16_t const * a) {
   return vld2q_f16(a);
 }
 
-// CHECK: test_vld2q_f32
+// CHECK-LABEL: test_vld2q_f32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x4x2_t test_vld2q_f32(float32_t const * a) {
   return vld2q_f32(a);
 }
 
-// CHECK: test_vld2q_p8
+// CHECK-LABEL: test_vld2q_p8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x16x2_t test_vld2q_p8(poly8_t const * a) {
   return vld2q_p8(a);
 }
 
-// CHECK: test_vld2q_p16
+// CHECK-LABEL: test_vld2q_p16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x8x2_t test_vld2q_p16(poly16_t const * a) {
   return vld2q_p16(a);
 }
 
-// CHECK: test_vld2_u8
+// CHECK-LABEL: test_vld2_u8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x8x2_t test_vld2_u8(uint8_t const * a) {
   return vld2_u8(a);
 }
 
-// CHECK: test_vld2_u16
+// CHECK-LABEL: test_vld2_u16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x4x2_t test_vld2_u16(uint16_t const * a) {
   return vld2_u16(a);
 }
 
-// CHECK: test_vld2_u32
+// CHECK-LABEL: test_vld2_u32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x2x2_t test_vld2_u32(uint32_t const * a) {
   return vld2_u32(a);
 }
 
-// CHECK: test_vld2_u64
+// CHECK-LABEL: test_vld2_u64
 // CHECK: vld1.64
 uint64x1x2_t test_vld2_u64(uint64_t const * a) {
   return vld2_u64(a);
 }
 
-// CHECK: test_vld2_s8
+// CHECK-LABEL: test_vld2_s8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x8x2_t test_vld2_s8(int8_t const * a) {
   return vld2_s8(a);
 }
 
-// CHECK: test_vld2_s16
+// CHECK-LABEL: test_vld2_s16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x4x2_t test_vld2_s16(int16_t const * a) {
   return vld2_s16(a);
 }
 
-// CHECK: test_vld2_s32
+// CHECK-LABEL: test_vld2_s32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x2x2_t test_vld2_s32(int32_t const * a) {
   return vld2_s32(a);
 }
 
-// CHECK: test_vld2_s64
+// CHECK-LABEL: test_vld2_s64
 // CHECK: vld1.64
 int64x1x2_t test_vld2_s64(int64_t const * a) {
   return vld2_s64(a);
 }
 
-// CHECK: test_vld2_f16
+// CHECK-LABEL: test_vld2_f16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x4x2_t test_vld2_f16(float16_t const * a) {
   return vld2_f16(a);
 }
 
-// CHECK: test_vld2_f32
+// CHECK-LABEL: test_vld2_f32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x2x2_t test_vld2_f32(float32_t const * a) {
   return vld2_f32(a);
 }
 
-// CHECK: test_vld2_p8
+// CHECK-LABEL: test_vld2_p8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x8x2_t test_vld2_p8(poly8_t const * a) {
   return vld2_p8(a);
 }
 
-// CHECK: test_vld2_p16
+// CHECK-LABEL: test_vld2_p16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x4x2_t test_vld2_p16(poly16_t const * a) {
   return vld2_p16(a);
 }
 
 
-// CHECK: test_vld2_dup_u8
+// CHECK-LABEL: test_vld2_dup_u8
 // CHECK: vld2.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x8x2_t test_vld2_dup_u8(uint8_t const * a) {
   return vld2_dup_u8(a);
 }
 
-// CHECK: test_vld2_dup_u16
+// CHECK-LABEL: test_vld2_dup_u16
 // CHECK: vld2.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint16x4x2_t test_vld2_dup_u16(uint16_t const * a) {
   return vld2_dup_u16(a);
 }
 
-// CHECK: test_vld2_dup_u32
+// CHECK-LABEL: test_vld2_dup_u32
 // CHECK: vld2.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint32x2x2_t test_vld2_dup_u32(uint32_t const * a) {
   return vld2_dup_u32(a);
 }
 
-// CHECK: test_vld2_dup_u64
+// CHECK-LABEL: test_vld2_dup_u64
 // CHECK: vld1.64
 uint64x1x2_t test_vld2_dup_u64(uint64_t const * a) {
   return vld2_dup_u64(a);
 }
 
-// CHECK: test_vld2_dup_s8
+// CHECK-LABEL: test_vld2_dup_s8
 // CHECK: vld2.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x8x2_t test_vld2_dup_s8(int8_t const * a) {
   return vld2_dup_s8(a);
 }
 
-// CHECK: test_vld2_dup_s16
+// CHECK-LABEL: test_vld2_dup_s16
 // CHECK: vld2.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int16x4x2_t test_vld2_dup_s16(int16_t const * a) {
   return vld2_dup_s16(a);
 }
 
-// CHECK: test_vld2_dup_s32
+// CHECK-LABEL: test_vld2_dup_s32
 // CHECK: vld2.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int32x2x2_t test_vld2_dup_s32(int32_t const * a) {
   return vld2_dup_s32(a);
 }
 
-// CHECK: test_vld2_dup_s64
+// CHECK-LABEL: test_vld2_dup_s64
 // CHECK: vld1.64
 int64x1x2_t test_vld2_dup_s64(int64_t const * a) {
   return vld2_dup_s64(a);
 }
 
-// CHECK: test_vld2_dup_f16
+// CHECK-LABEL: test_vld2_dup_f16
 // CHECK: vld2.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float16x4x2_t test_vld2_dup_f16(float16_t const * a) {
   return vld2_dup_f16(a);
 }
 
-// CHECK: test_vld2_dup_f32
+// CHECK-LABEL: test_vld2_dup_f32
 // CHECK: vld2.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float32x2x2_t test_vld2_dup_f32(float32_t const * a) {
   return vld2_dup_f32(a);
 }
 
-// CHECK: test_vld2_dup_p8
+// CHECK-LABEL: test_vld2_dup_p8
 // CHECK: vld2.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x8x2_t test_vld2_dup_p8(poly8_t const * a) {
   return vld2_dup_p8(a);
 }
 
-// CHECK: test_vld2_dup_p16
+// CHECK-LABEL: test_vld2_dup_p16
 // CHECK: vld2.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly16x4x2_t test_vld2_dup_p16(poly16_t const * a) {
   return vld2_dup_p16(a);
 }
 
 
-// CHECK: test_vld2q_lane_u16
+// CHECK-LABEL: test_vld2q_lane_u16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint16x8x2_t test_vld2q_lane_u16(uint16_t const * a, uint16x8x2_t b) {
   return vld2q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vld2q_lane_u32
+// CHECK-LABEL: test_vld2q_lane_u32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint32x4x2_t test_vld2q_lane_u32(uint32_t const * a, uint32x4x2_t b) {
   return vld2q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vld2q_lane_s16
+// CHECK-LABEL: test_vld2q_lane_s16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int16x8x2_t test_vld2q_lane_s16(int16_t const * a, int16x8x2_t b) {
   return vld2q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vld2q_lane_s32
+// CHECK-LABEL: test_vld2q_lane_s32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int32x4x2_t test_vld2q_lane_s32(int32_t const * a, int32x4x2_t b) {
   return vld2q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vld2q_lane_f16
+// CHECK-LABEL: test_vld2q_lane_f16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float16x8x2_t test_vld2q_lane_f16(float16_t const * a, float16x8x2_t b) {
   return vld2q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vld2q_lane_f32
+// CHECK-LABEL: test_vld2q_lane_f32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float32x4x2_t test_vld2q_lane_f32(float32_t const * a, float32x4x2_t b) {
   return vld2q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vld2q_lane_p16
+// CHECK-LABEL: test_vld2q_lane_p16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly16x8x2_t test_vld2q_lane_p16(poly16_t const * a, poly16x8x2_t b) {
   return vld2q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vld2_lane_u8
+// CHECK-LABEL: test_vld2_lane_u8
 // CHECK: vld2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x8x2_t test_vld2_lane_u8(uint8_t const * a, uint8x8x2_t b) {
   return vld2_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vld2_lane_u16
+// CHECK-LABEL: test_vld2_lane_u16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint16x4x2_t test_vld2_lane_u16(uint16_t const * a, uint16x4x2_t b) {
   return vld2_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vld2_lane_u32
+// CHECK-LABEL: test_vld2_lane_u32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint32x2x2_t test_vld2_lane_u32(uint32_t const * a, uint32x2x2_t b) {
   return vld2_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vld2_lane_s8
+// CHECK-LABEL: test_vld2_lane_s8
 // CHECK: vld2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x8x2_t test_vld2_lane_s8(int8_t const * a, int8x8x2_t b) {
   return vld2_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vld2_lane_s16
+// CHECK-LABEL: test_vld2_lane_s16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int16x4x2_t test_vld2_lane_s16(int16_t const * a, int16x4x2_t b) {
   return vld2_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vld2_lane_s32
+// CHECK-LABEL: test_vld2_lane_s32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int32x2x2_t test_vld2_lane_s32(int32_t const * a, int32x2x2_t b) {
   return vld2_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vld2_lane_f16
+// CHECK-LABEL: test_vld2_lane_f16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float16x4x2_t test_vld2_lane_f16(float16_t const * a, float16x4x2_t b) {
   return vld2_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vld2_lane_f32
+// CHECK-LABEL: test_vld2_lane_f32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float32x2x2_t test_vld2_lane_f32(float32_t const * a, float32x2x2_t b) {
   return vld2_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vld2_lane_p8
+// CHECK-LABEL: test_vld2_lane_p8
 // CHECK: vld2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x8x2_t test_vld2_lane_p8(poly8_t const * a, poly8x8x2_t b) {
   return vld2_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vld2_lane_p16
+// CHECK-LABEL: test_vld2_lane_p16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly16x4x2_t test_vld2_lane_p16(poly16_t const * a, poly16x4x2_t b) {
   return vld2_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vld3q_u8
+// CHECK-LABEL: test_vld3q_u8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint8x16x3_t test_vld3q_u8(uint8_t const * a) {
   return vld3q_u8(a);
 }
 
-// CHECK: test_vld3q_u16
+// CHECK-LABEL: test_vld3q_u16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint16x8x3_t test_vld3q_u16(uint16_t const * a) {
   return vld3q_u16(a);
 }
 
-// CHECK: test_vld3q_u32
+// CHECK-LABEL: test_vld3q_u32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint32x4x3_t test_vld3q_u32(uint32_t const * a) {
   return vld3q_u32(a);
 }
 
-// CHECK: test_vld3q_s8
+// CHECK-LABEL: test_vld3q_s8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int8x16x3_t test_vld3q_s8(int8_t const * a) {
   return vld3q_s8(a);
 }
 
-// CHECK: test_vld3q_s16
+// CHECK-LABEL: test_vld3q_s16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int16x8x3_t test_vld3q_s16(int16_t const * a) {
   return vld3q_s16(a);
 }
 
-// CHECK: test_vld3q_s32
+// CHECK-LABEL: test_vld3q_s32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int32x4x3_t test_vld3q_s32(int32_t const * a) {
   return vld3q_s32(a);
 }
 
-// CHECK: test_vld3q_f16
+// CHECK-LABEL: test_vld3q_f16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 float16x8x3_t test_vld3q_f16(float16_t const * a) {
   return vld3q_f16(a);
 }
 
-// CHECK: test_vld3q_f32
+// CHECK-LABEL: test_vld3q_f32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 float32x4x3_t test_vld3q_f32(float32_t const * a) {
   return vld3q_f32(a);
 }
 
-// CHECK: test_vld3q_p8
+// CHECK-LABEL: test_vld3q_p8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 poly8x16x3_t test_vld3q_p8(poly8_t const * a) {
   return vld3q_p8(a);
 }
 
-// CHECK: test_vld3q_p16
+// CHECK-LABEL: test_vld3q_p16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 poly16x8x3_t test_vld3q_p16(poly16_t const * a) {
   return vld3q_p16(a);
 }
 
-// CHECK: test_vld3_u8
+// CHECK-LABEL: test_vld3_u8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x8x3_t test_vld3_u8(uint8_t const * a) {
   return vld3_u8(a);
 }
 
-// CHECK: test_vld3_u16
+// CHECK-LABEL: test_vld3_u16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x4x3_t test_vld3_u16(uint16_t const * a) {
   return vld3_u16(a);
 }
 
-// CHECK: test_vld3_u32
+// CHECK-LABEL: test_vld3_u32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x2x3_t test_vld3_u32(uint32_t const * a) {
   return vld3_u32(a);
 }
 
-// CHECK: test_vld3_u64
+// CHECK-LABEL: test_vld3_u64
 // CHECK: vld1.64
 uint64x1x3_t test_vld3_u64(uint64_t const * a) {
   return vld3_u64(a);
 }
 
-// CHECK: test_vld3_s8
+// CHECK-LABEL: test_vld3_s8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x8x3_t test_vld3_s8(int8_t const * a) {
   return vld3_s8(a);
 }
 
-// CHECK: test_vld3_s16
+// CHECK-LABEL: test_vld3_s16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x4x3_t test_vld3_s16(int16_t const * a) {
   return vld3_s16(a);
 }
 
-// CHECK: test_vld3_s32
+// CHECK-LABEL: test_vld3_s32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x2x3_t test_vld3_s32(int32_t const * a) {
   return vld3_s32(a);
 }
 
-// CHECK: test_vld3_s64
+// CHECK-LABEL: test_vld3_s64
 // CHECK: vld1.64
 int64x1x3_t test_vld3_s64(int64_t const * a) {
   return vld3_s64(a);
 }
 
-// CHECK: test_vld3_f16
+// CHECK-LABEL: test_vld3_f16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x4x3_t test_vld3_f16(float16_t const * a) {
   return vld3_f16(a);
 }
 
-// CHECK: test_vld3_f32
+// CHECK-LABEL: test_vld3_f32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x2x3_t test_vld3_f32(float32_t const * a) {
   return vld3_f32(a);
 }
 
-// CHECK: test_vld3_p8
+// CHECK-LABEL: test_vld3_p8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x8x3_t test_vld3_p8(poly8_t const * a) {
   return vld3_p8(a);
 }
 
-// CHECK: test_vld3_p16
+// CHECK-LABEL: test_vld3_p16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x4x3_t test_vld3_p16(poly16_t const * a) {
   return vld3_p16(a);
 }
 
 
-// CHECK: test_vld3_dup_u8
+// CHECK-LABEL: test_vld3_dup_u8
 // CHECK: vld3.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x8x3_t test_vld3_dup_u8(uint8_t const * a) {
   return vld3_dup_u8(a);
 }
 
-// CHECK: test_vld3_dup_u16
+// CHECK-LABEL: test_vld3_dup_u16
 // CHECK: vld3.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint16x4x3_t test_vld3_dup_u16(uint16_t const * a) {
   return vld3_dup_u16(a);
 }
 
-// CHECK: test_vld3_dup_u32
+// CHECK-LABEL: test_vld3_dup_u32
 // CHECK: vld3.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint32x2x3_t test_vld3_dup_u32(uint32_t const * a) {
   return vld3_dup_u32(a);
 }
 
-// CHECK: test_vld3_dup_u64
+// CHECK-LABEL: test_vld3_dup_u64
 // CHECK: vld1.64
 uint64x1x3_t test_vld3_dup_u64(uint64_t const * a) {
   return vld3_dup_u64(a);
 }
 
-// CHECK: test_vld3_dup_s8
+// CHECK-LABEL: test_vld3_dup_s8
 // CHECK: vld3.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x8x3_t test_vld3_dup_s8(int8_t const * a) {
   return vld3_dup_s8(a);
 }
 
-// CHECK: test_vld3_dup_s16
+// CHECK-LABEL: test_vld3_dup_s16
 // CHECK: vld3.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int16x4x3_t test_vld3_dup_s16(int16_t const * a) {
   return vld3_dup_s16(a);
 }
 
-// CHECK: test_vld3_dup_s32
+// CHECK-LABEL: test_vld3_dup_s32
 // CHECK: vld3.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int32x2x3_t test_vld3_dup_s32(int32_t const * a) {
   return vld3_dup_s32(a);
 }
 
-// CHECK: test_vld3_dup_s64
+// CHECK-LABEL: test_vld3_dup_s64
 // CHECK: vld1.64
 int64x1x3_t test_vld3_dup_s64(int64_t const * a) {
   return vld3_dup_s64(a);
 }
 
-// CHECK: test_vld3_dup_f16
+// CHECK-LABEL: test_vld3_dup_f16
 // CHECK: vld3.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float16x4x3_t test_vld3_dup_f16(float16_t const * a) {
   return vld3_dup_f16(a);
 }
 
-// CHECK: test_vld3_dup_f32
+// CHECK-LABEL: test_vld3_dup_f32
 // CHECK: vld3.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float32x2x3_t test_vld3_dup_f32(float32_t const * a) {
   return vld3_dup_f32(a);
 }
 
-// CHECK: test_vld3_dup_p8
+// CHECK-LABEL: test_vld3_dup_p8
 // CHECK: vld3.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x8x3_t test_vld3_dup_p8(poly8_t const * a) {
   return vld3_dup_p8(a);
 }
 
-// CHECK: test_vld3_dup_p16
+// CHECK-LABEL: test_vld3_dup_p16
 // CHECK: vld3.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly16x4x3_t test_vld3_dup_p16(poly16_t const * a) {
   return vld3_dup_p16(a);
 }
 
 
-// CHECK: test_vld3q_lane_u16
+// CHECK-LABEL: test_vld3q_lane_u16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 uint16x8x3_t test_vld3q_lane_u16(uint16_t const * a, uint16x8x3_t b) {
   return vld3q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vld3q_lane_u32
+// CHECK-LABEL: test_vld3q_lane_u32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 uint32x4x3_t test_vld3q_lane_u32(uint32_t const * a, uint32x4x3_t b) {
   return vld3q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vld3q_lane_s16
+// CHECK-LABEL: test_vld3q_lane_s16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 int16x8x3_t test_vld3q_lane_s16(int16_t const * a, int16x8x3_t b) {
   return vld3q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vld3q_lane_s32
+// CHECK-LABEL: test_vld3q_lane_s32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 int32x4x3_t test_vld3q_lane_s32(int32_t const * a, int32x4x3_t b) {
   return vld3q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vld3q_lane_f16
+// CHECK-LABEL: test_vld3q_lane_f16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 float16x8x3_t test_vld3q_lane_f16(float16_t const * a, float16x8x3_t b) {
   return vld3q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vld3q_lane_f32
+// CHECK-LABEL: test_vld3q_lane_f32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 float32x4x3_t test_vld3q_lane_f32(float32_t const * a, float32x4x3_t b) {
   return vld3q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vld3q_lane_p16
+// CHECK-LABEL: test_vld3q_lane_p16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 poly16x8x3_t test_vld3q_lane_p16(poly16_t const * a, poly16x8x3_t b) {
   return vld3q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vld3_lane_u8
+// CHECK-LABEL: test_vld3_lane_u8
 // CHECK: vld3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x8x3_t test_vld3_lane_u8(uint8_t const * a, uint8x8x3_t b) {
   return vld3_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vld3_lane_u16
+// CHECK-LABEL: test_vld3_lane_u16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint16x4x3_t test_vld3_lane_u16(uint16_t const * a, uint16x4x3_t b) {
   return vld3_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vld3_lane_u32
+// CHECK-LABEL: test_vld3_lane_u32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint32x2x3_t test_vld3_lane_u32(uint32_t const * a, uint32x2x3_t b) {
   return vld3_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vld3_lane_s8
+// CHECK-LABEL: test_vld3_lane_s8
 // CHECK: vld3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x8x3_t test_vld3_lane_s8(int8_t const * a, int8x8x3_t b) {
   return vld3_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vld3_lane_s16
+// CHECK-LABEL: test_vld3_lane_s16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int16x4x3_t test_vld3_lane_s16(int16_t const * a, int16x4x3_t b) {
   return vld3_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vld3_lane_s32
+// CHECK-LABEL: test_vld3_lane_s32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int32x2x3_t test_vld3_lane_s32(int32_t const * a, int32x2x3_t b) {
   return vld3_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vld3_lane_f16
+// CHECK-LABEL: test_vld3_lane_f16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float16x4x3_t test_vld3_lane_f16(float16_t const * a, float16x4x3_t b) {
   return vld3_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vld3_lane_f32
+// CHECK-LABEL: test_vld3_lane_f32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float32x2x3_t test_vld3_lane_f32(float32_t const * a, float32x2x3_t b) {
   return vld3_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vld3_lane_p8
+// CHECK-LABEL: test_vld3_lane_p8
 // CHECK: vld3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x8x3_t test_vld3_lane_p8(poly8_t const * a, poly8x8x3_t b) {
   return vld3_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vld3_lane_p16
+// CHECK-LABEL: test_vld3_lane_p16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly16x4x3_t test_vld3_lane_p16(poly16_t const * a, poly16x4x3_t b) {
   return vld3_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vld4q_u8
+// CHECK-LABEL: test_vld4q_u8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint8x16x4_t test_vld4q_u8(uint8_t const * a) {
   return vld4q_u8(a);
 }
 
-// CHECK: test_vld4q_u16
+// CHECK-LABEL: test_vld4q_u16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint16x8x4_t test_vld4q_u16(uint16_t const * a) {
   return vld4q_u16(a);
 }
 
-// CHECK: test_vld4q_u32
+// CHECK-LABEL: test_vld4q_u32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint32x4x4_t test_vld4q_u32(uint32_t const * a) {
   return vld4q_u32(a);
 }
 
-// CHECK: test_vld4q_s8
+// CHECK-LABEL: test_vld4q_s8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int8x16x4_t test_vld4q_s8(int8_t const * a) {
   return vld4q_s8(a);
 }
 
-// CHECK: test_vld4q_s16
+// CHECK-LABEL: test_vld4q_s16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int16x8x4_t test_vld4q_s16(int16_t const * a) {
   return vld4q_s16(a);
 }
 
-// CHECK: test_vld4q_s32
+// CHECK-LABEL: test_vld4q_s32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int32x4x4_t test_vld4q_s32(int32_t const * a) {
   return vld4q_s32(a);
 }
 
-// CHECK: test_vld4q_f16
+// CHECK-LABEL: test_vld4q_f16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 float16x8x4_t test_vld4q_f16(float16_t const * a) {
   return vld4q_f16(a);
 }
 
-// CHECK: test_vld4q_f32
+// CHECK-LABEL: test_vld4q_f32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 float32x4x4_t test_vld4q_f32(float32_t const * a) {
   return vld4q_f32(a);
 }
 
-// CHECK: test_vld4q_p8
+// CHECK-LABEL: test_vld4q_p8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 poly8x16x4_t test_vld4q_p8(poly8_t const * a) {
   return vld4q_p8(a);
 }
 
-// CHECK: test_vld4q_p16
+// CHECK-LABEL: test_vld4q_p16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 poly16x8x4_t test_vld4q_p16(poly16_t const * a) {
   return vld4q_p16(a);
 }
 
-// CHECK: test_vld4_u8
+// CHECK-LABEL: test_vld4_u8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x8x4_t test_vld4_u8(uint8_t const * a) {
   return vld4_u8(a);
 }
 
-// CHECK: test_vld4_u16
+// CHECK-LABEL: test_vld4_u16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x4x4_t test_vld4_u16(uint16_t const * a) {
   return vld4_u16(a);
 }
 
-// CHECK: test_vld4_u32
+// CHECK-LABEL: test_vld4_u32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x2x4_t test_vld4_u32(uint32_t const * a) {
   return vld4_u32(a);
 }
 
-// CHECK: test_vld4_u64
+// CHECK-LABEL: test_vld4_u64
 // CHECK: vld1.64
 uint64x1x4_t test_vld4_u64(uint64_t const * a) {
   return vld4_u64(a);
 }
 
-// CHECK: test_vld4_s8
+// CHECK-LABEL: test_vld4_s8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x8x4_t test_vld4_s8(int8_t const * a) {
   return vld4_s8(a);
 }
 
-// CHECK: test_vld4_s16
+// CHECK-LABEL: test_vld4_s16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x4x4_t test_vld4_s16(int16_t const * a) {
   return vld4_s16(a);
 }
 
-// CHECK: test_vld4_s32
+// CHECK-LABEL: test_vld4_s32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x2x4_t test_vld4_s32(int32_t const * a) {
   return vld4_s32(a);
 }
 
-// CHECK: test_vld4_s64
+// CHECK-LABEL: test_vld4_s64
 // CHECK: vld1.64
 int64x1x4_t test_vld4_s64(int64_t const * a) {
   return vld4_s64(a);
 }
 
-// CHECK: test_vld4_f16
+// CHECK-LABEL: test_vld4_f16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x4x4_t test_vld4_f16(float16_t const * a) {
   return vld4_f16(a);
 }
 
-// CHECK: test_vld4_f32
+// CHECK-LABEL: test_vld4_f32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x2x4_t test_vld4_f32(float32_t const * a) {
   return vld4_f32(a);
 }
 
-// CHECK: test_vld4_p8
+// CHECK-LABEL: test_vld4_p8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x8x4_t test_vld4_p8(poly8_t const * a) {
   return vld4_p8(a);
 }
 
-// CHECK: test_vld4_p16
+// CHECK-LABEL: test_vld4_p16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x4x4_t test_vld4_p16(poly16_t const * a) {
   return vld4_p16(a);
 }
 
 
-// CHECK: test_vld4_dup_u8
+// CHECK-LABEL: test_vld4_dup_u8
 // CHECK: vld4.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x8x4_t test_vld4_dup_u8(uint8_t const * a) {
   return vld4_dup_u8(a);
 }
 
-// CHECK: test_vld4_dup_u16
+// CHECK-LABEL: test_vld4_dup_u16
 // CHECK: vld4.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint16x4x4_t test_vld4_dup_u16(uint16_t const * a) {
   return vld4_dup_u16(a);
 }
 
-// CHECK: test_vld4_dup_u32
+// CHECK-LABEL: test_vld4_dup_u32
 // CHECK: vld4.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint32x2x4_t test_vld4_dup_u32(uint32_t const * a) {
   return vld4_dup_u32(a);
 }
 
-// CHECK: test_vld4_dup_u64
+// CHECK-LABEL: test_vld4_dup_u64
 // CHECK: vld1.64
 uint64x1x4_t test_vld4_dup_u64(uint64_t const * a) {
   return vld4_dup_u64(a);
 }
 
-// CHECK: test_vld4_dup_s8
+// CHECK-LABEL: test_vld4_dup_s8
 // CHECK: vld4.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x8x4_t test_vld4_dup_s8(int8_t const * a) {
   return vld4_dup_s8(a);
 }
 
-// CHECK: test_vld4_dup_s16
+// CHECK-LABEL: test_vld4_dup_s16
 // CHECK: vld4.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int16x4x4_t test_vld4_dup_s16(int16_t const * a) {
   return vld4_dup_s16(a);
 }
 
-// CHECK: test_vld4_dup_s32
+// CHECK-LABEL: test_vld4_dup_s32
 // CHECK: vld4.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int32x2x4_t test_vld4_dup_s32(int32_t const * a) {
   return vld4_dup_s32(a);
 }
 
-// CHECK: test_vld4_dup_s64
+// CHECK-LABEL: test_vld4_dup_s64
 // CHECK: vld1.64
 int64x1x4_t test_vld4_dup_s64(int64_t const * a) {
   return vld4_dup_s64(a);
 }
 
-// CHECK: test_vld4_dup_f16
+// CHECK-LABEL: test_vld4_dup_f16
 // CHECK: vld4.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float16x4x4_t test_vld4_dup_f16(float16_t const * a) {
   return vld4_dup_f16(a);
 }
 
-// CHECK: test_vld4_dup_f32
+// CHECK-LABEL: test_vld4_dup_f32
 // CHECK: vld4.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float32x2x4_t test_vld4_dup_f32(float32_t const * a) {
   return vld4_dup_f32(a);
 }
 
-// CHECK: test_vld4_dup_p8
+// CHECK-LABEL: test_vld4_dup_p8
 // CHECK: vld4.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x8x4_t test_vld4_dup_p8(poly8_t const * a) {
   return vld4_dup_p8(a);
 }
 
-// CHECK: test_vld4_dup_p16
+// CHECK-LABEL: test_vld4_dup_p16
 // CHECK: vld4.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly16x4x4_t test_vld4_dup_p16(poly16_t const * a) {
   return vld4_dup_p16(a);
 }
 
 
-// CHECK: test_vld4q_lane_u16
+// CHECK-LABEL: test_vld4q_lane_u16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 uint16x8x4_t test_vld4q_lane_u16(uint16_t const * a, uint16x8x4_t b) {
   return vld4q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vld4q_lane_u32
+// CHECK-LABEL: test_vld4q_lane_u32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 uint32x4x4_t test_vld4q_lane_u32(uint32_t const * a, uint32x4x4_t b) {
   return vld4q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vld4q_lane_s16
+// CHECK-LABEL: test_vld4q_lane_s16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 int16x8x4_t test_vld4q_lane_s16(int16_t const * a, int16x8x4_t b) {
   return vld4q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vld4q_lane_s32
+// CHECK-LABEL: test_vld4q_lane_s32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 int32x4x4_t test_vld4q_lane_s32(int32_t const * a, int32x4x4_t b) {
   return vld4q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vld4q_lane_f16
+// CHECK-LABEL: test_vld4q_lane_f16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 float16x8x4_t test_vld4q_lane_f16(float16_t const * a, float16x8x4_t b) {
   return vld4q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vld4q_lane_f32
+// CHECK-LABEL: test_vld4q_lane_f32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 float32x4x4_t test_vld4q_lane_f32(float32_t const * a, float32x4x4_t b) {
   return vld4q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vld4q_lane_p16
+// CHECK-LABEL: test_vld4q_lane_p16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 poly16x8x4_t test_vld4q_lane_p16(poly16_t const * a, poly16x8x4_t b) {
   return vld4q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vld4_lane_u8
+// CHECK-LABEL: test_vld4_lane_u8
 // CHECK: vld4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x8x4_t test_vld4_lane_u8(uint8_t const * a, uint8x8x4_t b) {
   return vld4_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vld4_lane_u16
+// CHECK-LABEL: test_vld4_lane_u16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint16x4x4_t test_vld4_lane_u16(uint16_t const * a, uint16x4x4_t b) {
   return vld4_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vld4_lane_u32
+// CHECK-LABEL: test_vld4_lane_u32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint32x2x4_t test_vld4_lane_u32(uint32_t const * a, uint32x2x4_t b) {
   return vld4_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vld4_lane_s8
+// CHECK-LABEL: test_vld4_lane_s8
 // CHECK: vld4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x8x4_t test_vld4_lane_s8(int8_t const * a, int8x8x4_t b) {
   return vld4_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vld4_lane_s16
+// CHECK-LABEL: test_vld4_lane_s16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int16x4x4_t test_vld4_lane_s16(int16_t const * a, int16x4x4_t b) {
   return vld4_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vld4_lane_s32
+// CHECK-LABEL: test_vld4_lane_s32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int32x2x4_t test_vld4_lane_s32(int32_t const * a, int32x2x4_t b) {
   return vld4_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vld4_lane_f16
+// CHECK-LABEL: test_vld4_lane_f16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float16x4x4_t test_vld4_lane_f16(float16_t const * a, float16x4x4_t b) {
   return vld4_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vld4_lane_f32
+// CHECK-LABEL: test_vld4_lane_f32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float32x2x4_t test_vld4_lane_f32(float32_t const * a, float32x2x4_t b) {
   return vld4_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vld4_lane_p8
+// CHECK-LABEL: test_vld4_lane_p8
 // CHECK: vld4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x8x4_t test_vld4_lane_p8(poly8_t const * a, poly8x8x4_t b) {
   return vld4_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vld4_lane_p16
+// CHECK-LABEL: test_vld4_lane_p16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly16x4x4_t test_vld4_lane_p16(poly16_t const * a, poly16x4x4_t b) {
   return vld4_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vmax_s8
+// CHECK-LABEL: test_vmax_s8
 // CHECK: vmax.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmax_s8(int8x8_t a, int8x8_t b) {
   return vmax_s8(a, b);
 }
 
-// CHECK: test_vmax_s16
+// CHECK-LABEL: test_vmax_s16
 // CHECK: vmax.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmax_s16(int16x4_t a, int16x4_t b) {
   return vmax_s16(a, b);
 }
 
-// CHECK: test_vmax_s32
+// CHECK-LABEL: test_vmax_s32
 // CHECK: vmax.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmax_s32(int32x2_t a, int32x2_t b) {
   return vmax_s32(a, b);
 }
 
-// CHECK: test_vmax_u8
+// CHECK-LABEL: test_vmax_u8
 // CHECK: vmax.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmax_u8(uint8x8_t a, uint8x8_t b) {
   return vmax_u8(a, b);
 }
 
-// CHECK: test_vmax_u16
+// CHECK-LABEL: test_vmax_u16
 // CHECK: vmax.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmax_u16(uint16x4_t a, uint16x4_t b) {
   return vmax_u16(a, b);
 }
 
-// CHECK: test_vmax_u32
+// CHECK-LABEL: test_vmax_u32
 // CHECK: vmax.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmax_u32(uint32x2_t a, uint32x2_t b) {
   return vmax_u32(a, b);
 }
 
-// CHECK: test_vmax_f32
+// CHECK-LABEL: test_vmax_f32
 // CHECK: vmax.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmax_f32(float32x2_t a, float32x2_t b) {
   return vmax_f32(a, b);
 }
 
-// CHECK: test_vmaxq_s8
+// CHECK-LABEL: test_vmaxq_s8
 // CHECK: vmax.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmaxq_s8(int8x16_t a, int8x16_t b) {
   return vmaxq_s8(a, b);
 }
 
-// CHECK: test_vmaxq_s16
+// CHECK-LABEL: test_vmaxq_s16
 // CHECK: vmax.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmaxq_s16(int16x8_t a, int16x8_t b) {
   return vmaxq_s16(a, b);
 }
 
-// CHECK: test_vmaxq_s32
+// CHECK-LABEL: test_vmaxq_s32
 // CHECK: vmax.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmaxq_s32(int32x4_t a, int32x4_t b) {
   return vmaxq_s32(a, b);
 }
 
-// CHECK: test_vmaxq_u8
+// CHECK-LABEL: test_vmaxq_u8
 // CHECK: vmax.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmaxq_u8(uint8x16_t a, uint8x16_t b) {
   return vmaxq_u8(a, b);
 }
 
-// CHECK: test_vmaxq_u16
+// CHECK-LABEL: test_vmaxq_u16
 // CHECK: vmax.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmaxq_u16(uint16x8_t a, uint16x8_t b) {
   return vmaxq_u16(a, b);
 }
 
-// CHECK: test_vmaxq_u32
+// CHECK-LABEL: test_vmaxq_u32
 // CHECK: vmax.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmaxq_u32(uint32x4_t a, uint32x4_t b) {
   return vmaxq_u32(a, b);
 }
 
-// CHECK: test_vmaxq_f32
+// CHECK-LABEL: test_vmaxq_f32
 // CHECK: vmax.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmaxq_f32(float32x4_t a, float32x4_t b) {
   return vmaxq_f32(a, b);
 }
 
 
-// CHECK: test_vmin_s8
+// CHECK-LABEL: test_vmin_s8
 // CHECK: vmin.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmin_s8(int8x8_t a, int8x8_t b) {
   return vmin_s8(a, b);
 }
 
-// CHECK: test_vmin_s16
+// CHECK-LABEL: test_vmin_s16
 // CHECK: vmin.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmin_s16(int16x4_t a, int16x4_t b) {
   return vmin_s16(a, b);
 }
 
-// CHECK: test_vmin_s32
+// CHECK-LABEL: test_vmin_s32
 // CHECK: vmin.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmin_s32(int32x2_t a, int32x2_t b) {
   return vmin_s32(a, b);
 }
 
-// CHECK: test_vmin_u8
+// CHECK-LABEL: test_vmin_u8
 // CHECK: vmin.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmin_u8(uint8x8_t a, uint8x8_t b) {
   return vmin_u8(a, b);
 }
 
-// CHECK: test_vmin_u16
+// CHECK-LABEL: test_vmin_u16
 // CHECK: vmin.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmin_u16(uint16x4_t a, uint16x4_t b) {
   return vmin_u16(a, b);
 }
 
-// CHECK: test_vmin_u32
+// CHECK-LABEL: test_vmin_u32
 // CHECK: vmin.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmin_u32(uint32x2_t a, uint32x2_t b) {
   return vmin_u32(a, b);
 }
 
-// CHECK: test_vmin_f32
+// CHECK-LABEL: test_vmin_f32
 // CHECK: vmin.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmin_f32(float32x2_t a, float32x2_t b) {
   return vmin_f32(a, b);
 }
 
-// CHECK: test_vminq_s8
+// CHECK-LABEL: test_vminq_s8
 // CHECK: vmin.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vminq_s8(int8x16_t a, int8x16_t b) {
   return vminq_s8(a, b);
 }
 
-// CHECK: test_vminq_s16
+// CHECK-LABEL: test_vminq_s16
 // CHECK: vmin.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vminq_s16(int16x8_t a, int16x8_t b) {
   return vminq_s16(a, b);
 }
 
-// CHECK: test_vminq_s32
+// CHECK-LABEL: test_vminq_s32
 // CHECK: vmin.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vminq_s32(int32x4_t a, int32x4_t b) {
   return vminq_s32(a, b);
 }
 
-// CHECK: test_vminq_u8
+// CHECK-LABEL: test_vminq_u8
 // CHECK: vmin.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vminq_u8(uint8x16_t a, uint8x16_t b) {
   return vminq_u8(a, b);
 }
 
-// CHECK: test_vminq_u16
+// CHECK-LABEL: test_vminq_u16
 // CHECK: vmin.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vminq_u16(uint16x8_t a, uint16x8_t b) {
   return vminq_u16(a, b);
 }
 
-// CHECK: test_vminq_u32
+// CHECK-LABEL: test_vminq_u32
 // CHECK: vmin.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vminq_u32(uint32x4_t a, uint32x4_t b) {
   return vminq_u32(a, b);
 }
 
-// CHECK: test_vminq_f32
+// CHECK-LABEL: test_vminq_f32
 // CHECK: vmin.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vminq_f32(float32x4_t a, float32x4_t b) {
   return vminq_f32(a, b);
 }
 
 
-// CHECK: test_vmla_s8
+// CHECK-LABEL: test_vmla_s8
 // CHECK: vmla.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmla_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
   return vmla_s8(a, b, c);
 }
 
-// CHECK: test_vmla_s16
+// CHECK-LABEL: test_vmla_s16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmla_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vmla_s16(a, b, c);
 }
 
-// CHECK: test_vmla_s32
+// CHECK-LABEL: test_vmla_s32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmla_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vmla_s32(a, b, c);
 }
 
-// CHECK: test_vmla_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmla_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmla_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vmla_f32(a, b, c);
 }
 
-// CHECK: test_vmla_u8
+// CHECK-LABEL: test_vmla_u8
 // CHECK: vmla.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmla_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vmla_u8(a, b, c);
 }
 
-// CHECK: test_vmla_u16
+// CHECK-LABEL: test_vmla_u16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmla_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmla_u16(a, b, c);
 }
 
-// CHECK: test_vmla_u32
+// CHECK-LABEL: test_vmla_u32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmla_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmla_u32(a, b, c);
 }
 
-// CHECK: test_vmlaq_s8
+// CHECK-LABEL: test_vmlaq_s8
 // CHECK: vmla.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmlaq_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
   return vmlaq_s8(a, b, c);
 }
 
-// CHECK: test_vmlaq_s16
+// CHECK-LABEL: test_vmlaq_s16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmlaq_s16(int16x8_t a, int16x8_t b, int16x8_t c) {
   return vmlaq_s16(a, b, c);
 }
 
-// CHECK: test_vmlaq_s32
+// CHECK-LABEL: test_vmlaq_s32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmlaq_s32(int32x4_t a, int32x4_t b, int32x4_t c) {
   return vmlaq_s32(a, b, c);
 }
 
-// CHECK: test_vmlaq_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmlaq_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmlaq_f32(float32x4_t a, float32x4_t b, float32x4_t c) {
   return vmlaq_f32(a, b, c);
 }
 
-// CHECK: test_vmlaq_u8
+// CHECK-LABEL: test_vmlaq_u8
 // CHECK: vmla.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmlaq_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
   return vmlaq_u8(a, b, c);
 }
 
-// CHECK: test_vmlaq_u16
+// CHECK-LABEL: test_vmlaq_u16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmlaq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t c) {
   return vmlaq_u16(a, b, c);
 }
 
-// CHECK: test_vmlaq_u32
+// CHECK-LABEL: test_vmlaq_u32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmlaq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
   return vmlaq_u32(a, b, c);
 }
 
 
-// CHECK: test_vmlal_s8
+// CHECK-LABEL: test_vmlal_s8
 // CHECK: vmlal.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vmlal_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
   return vmlal_s8(a, b, c);
 }
 
-// CHECK: test_vmlal_s16
+// CHECK-LABEL: test_vmlal_s16
 // CHECK: vmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmlal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vmlal_s16(a, b, c);
 }
 
-// CHECK: test_vmlal_s32
+// CHECK-LABEL: test_vmlal_s32
 // CHECK: vmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmlal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vmlal_s32(a, b, c);
 }
 
-// CHECK: test_vmlal_u8
+// CHECK-LABEL: test_vmlal_u8
 // CHECK: vmlal.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vmlal_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
   return vmlal_u8(a, b, c);
 }
 
-// CHECK: test_vmlal_u16
+// CHECK-LABEL: test_vmlal_u16
 // CHECK: vmlal.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmlal_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmlal_u16(a, b, c);
 }
 
-// CHECK: test_vmlal_u32
+// CHECK-LABEL: test_vmlal_u32
 // CHECK: vmlal.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmlal_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmlal_u32(a, b, c);
 }
 
 
-// CHECK: test_vmlal_lane_s16
+// CHECK-LABEL: test_vmlal_lane_s16
 // CHECK: vmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmlal_lane_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vmlal_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmlal_lane_s32
+// CHECK-LABEL: test_vmlal_lane_s32
 // CHECK: vmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vmlal_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vmlal_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmlal_lane_u16
+// CHECK-LABEL: test_vmlal_lane_u16
 // CHECK: vmlal.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmlal_lane_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmlal_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmlal_lane_u32
+// CHECK-LABEL: test_vmlal_lane_u32
 // CHECK: vmlal.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint64x2_t test_vmlal_lane_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmlal_lane_u32(a, b, c, 1);
 }
 
 
-// CHECK: test_vmlal_n_s16
+// CHECK-LABEL: test_vmlal_n_s16
 // CHECK: vmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
   return vmlal_n_s16(a, b, c);
 }
 
-// CHECK: test_vmlal_n_s32
+// CHECK-LABEL: test_vmlal_n_s32
 // CHECK: vmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
   return vmlal_n_s32(a, b, c);
 }
 
-// CHECK: test_vmlal_n_u16
+// CHECK-LABEL: test_vmlal_n_u16
 // CHECK: vmlal.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmlal_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) {
   return vmlal_n_u16(a, b, c);
 }
 
-// CHECK: test_vmlal_n_u32
+// CHECK-LABEL: test_vmlal_n_u32
 // CHECK: vmlal.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmlal_n_u32(uint64x2_t a, uint32x2_t b, uint32_t c) {
   return vmlal_n_u32(a, b, c);
 }
 
 
-// CHECK: test_vmla_lane_s16
+// CHECK-LABEL: test_vmla_lane_s16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vmla_lane_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vmla_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmla_lane_s32
+// CHECK-LABEL: test_vmla_lane_s32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vmla_lane_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vmla_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmla_lane_u16
+// CHECK-LABEL: test_vmla_lane_u16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x4_t test_vmla_lane_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmla_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmla_lane_u32
+// CHECK-LABEL: test_vmla_lane_u32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x2_t test_vmla_lane_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmla_lane_u32(a, b, c, 1);
 }
 
-// CHECK: test_vmla_lane_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmla_lane_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x2_t test_vmla_lane_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vmla_lane_f32(a, b, c, 1);
 }
 
-// CHECK: test_vmlaq_lane_s16
+// CHECK-LABEL: test_vmlaq_lane_s16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vmlaq_lane_s16(int16x8_t a, int16x8_t b, int16x4_t c) {
   return vmlaq_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmlaq_lane_s32
+// CHECK-LABEL: test_vmlaq_lane_s32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmlaq_lane_s32(int32x4_t a, int32x4_t b, int32x2_t c) {
   return vmlaq_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmlaq_lane_u16
+// CHECK-LABEL: test_vmlaq_lane_u16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x8_t test_vmlaq_lane_u16(uint16x8_t a, uint16x8_t b, uint16x4_t c) {
   return vmlaq_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmlaq_lane_u32
+// CHECK-LABEL: test_vmlaq_lane_u32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmlaq_lane_u32(uint32x4_t a, uint32x4_t b, uint32x2_t c) {
   return vmlaq_lane_u32(a, b, c, 1);
 }
 
-// CHECK: test_vmlaq_lane_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmlaq_lane_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x4_t test_vmlaq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t c) {
   return vmlaq_lane_f32(a, b, c, 1);
 }
 
 
-// CHECK: test_vmla_n_s16
+// CHECK-LABEL: test_vmla_n_s16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmla_n_s16(int16x4_t a, int16x4_t b, int16_t c) {
   return vmla_n_s16(a, b, c);
 }
 
-// CHECK: test_vmla_n_s32
+// CHECK-LABEL: test_vmla_n_s32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmla_n_s32(int32x2_t a, int32x2_t b, int32_t c) {
   return vmla_n_s32(a, b, c);
 }
 
-// CHECK: test_vmla_n_u16
+// CHECK-LABEL: test_vmla_n_u16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmla_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) {
   return vmla_n_u16(a, b, c);
 }
 
-// CHECK: test_vmla_n_u32
+// CHECK-LABEL: test_vmla_n_u32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmla_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) {
   return vmla_n_u32(a, b, c);
 }
 
-// CHECK: test_vmla_n_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmla_n_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmla_n_f32(float32x2_t a, float32x2_t b, float32_t c) {
   return vmla_n_f32(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_s16
+// CHECK-LABEL: test_vmlaq_n_s16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmlaq_n_s16(int16x8_t a, int16x8_t b, int16_t c) {
   return vmlaq_n_s16(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_s32
+// CHECK-LABEL: test_vmlaq_n_s32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmlaq_n_s32(int32x4_t a, int32x4_t b, int32_t c) {
   return vmlaq_n_s32(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_u16
+// CHECK-LABEL: test_vmlaq_n_u16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmlaq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) {
   return vmlaq_n_u16(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_u32
+// CHECK-LABEL: test_vmlaq_n_u32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmlaq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) {
   return vmlaq_n_u32(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmlaq_n_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vld1.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, 
+// CHECK-A57: vmla.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmlaq_n_f32(float32x4_t a, float32x4_t b, float32_t c) {
   return vmlaq_n_f32(a, b, c);
 }
 
 
-// CHECK: test_vmls_s8
+// CHECK-LABEL: test_vmls_s8
 // CHECK: vmls.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmls_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
   return vmls_s8(a, b, c);
 }
 
-// CHECK: test_vmls_s16
+// CHECK-LABEL: test_vmls_s16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmls_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vmls_s16(a, b, c);
 }
 
-// CHECK: test_vmls_s32
+// CHECK-LABEL: test_vmls_s32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmls_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vmls_s32(a, b, c);
 }
 
-// CHECK: test_vmls_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmls_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmls_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vmls_f32(a, b, c);
 }
 
-// CHECK: test_vmls_u8
+// CHECK-LABEL: test_vmls_u8
 // CHECK: vmls.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmls_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vmls_u8(a, b, c);
 }
 
-// CHECK: test_vmls_u16
+// CHECK-LABEL: test_vmls_u16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmls_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmls_u16(a, b, c);
 }
 
-// CHECK: test_vmls_u32
+// CHECK-LABEL: test_vmls_u32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmls_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmls_u32(a, b, c);
 }
 
-// CHECK: test_vmlsq_s8
+// CHECK-LABEL: test_vmlsq_s8
 // CHECK: vmls.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmlsq_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
   return vmlsq_s8(a, b, c);
 }
 
-// CHECK: test_vmlsq_s16
+// CHECK-LABEL: test_vmlsq_s16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmlsq_s16(int16x8_t a, int16x8_t b, int16x8_t c) {
   return vmlsq_s16(a, b, c);
 }
 
-// CHECK: test_vmlsq_s32
+// CHECK-LABEL: test_vmlsq_s32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmlsq_s32(int32x4_t a, int32x4_t b, int32x4_t c) {
   return vmlsq_s32(a, b, c);
 }
 
-// CHECK: test_vmlsq_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmlsq_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmlsq_f32(float32x4_t a, float32x4_t b, float32x4_t c) {
   return vmlsq_f32(a, b, c);
 }
 
-// CHECK: test_vmlsq_u8
+// CHECK-LABEL: test_vmlsq_u8
 // CHECK: vmls.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmlsq_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
   return vmlsq_u8(a, b, c);
 }
 
-// CHECK: test_vmlsq_u16
+// CHECK-LABEL: test_vmlsq_u16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmlsq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t c) {
   return vmlsq_u16(a, b, c);
 }
 
-// CHECK: test_vmlsq_u32
+// CHECK-LABEL: test_vmlsq_u32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmlsq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
   return vmlsq_u32(a, b, c);
 }
 
 
-// CHECK: test_vmlsl_s8
+// CHECK-LABEL: test_vmlsl_s8
 // CHECK: vmlsl.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vmlsl_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
   return vmlsl_s8(a, b, c);
 }
 
-// CHECK: test_vmlsl_s16
+// CHECK-LABEL: test_vmlsl_s16
 // CHECK: vmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmlsl_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vmlsl_s16(a, b, c);
 }
 
-// CHECK: test_vmlsl_s32
+// CHECK-LABEL: test_vmlsl_s32
 // CHECK: vmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmlsl_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vmlsl_s32(a, b, c);
 }
 
-// CHECK: test_vmlsl_u8
+// CHECK-LABEL: test_vmlsl_u8
 // CHECK: vmlsl.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vmlsl_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
   return vmlsl_u8(a, b, c);
 }
 
-// CHECK: test_vmlsl_u16
+// CHECK-LABEL: test_vmlsl_u16
 // CHECK: vmlsl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmlsl_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmlsl_u16(a, b, c);
 }
 
-// CHECK: test_vmlsl_u32
+// CHECK-LABEL: test_vmlsl_u32
 // CHECK: vmlsl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmlsl_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmlsl_u32(a, b, c);
 }
 
 
-// CHECK: test_vmlsl_lane_s16
+// CHECK-LABEL: test_vmlsl_lane_s16
 // CHECK: vmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmlsl_lane_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vmlsl_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmlsl_lane_s32
+// CHECK-LABEL: test_vmlsl_lane_s32
 // CHECK: vmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vmlsl_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vmlsl_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmlsl_lane_u16
+// CHECK-LABEL: test_vmlsl_lane_u16
 // CHECK: vmlsl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmlsl_lane_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmlsl_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmlsl_lane_u32
+// CHECK-LABEL: test_vmlsl_lane_u32
 // CHECK: vmlsl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint64x2_t test_vmlsl_lane_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmlsl_lane_u32(a, b, c, 1);
 }
 
 
-// CHECK: test_vmlsl_n_s16
+// CHECK-LABEL: test_vmlsl_n_s16
 // CHECK: vmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
   return vmlsl_n_s16(a, b, c);
 }
 
-// CHECK: test_vmlsl_n_s32
+// CHECK-LABEL: test_vmlsl_n_s32
 // CHECK: vmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmlsl_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
   return vmlsl_n_s32(a, b, c);
 }
 
-// CHECK: test_vmlsl_n_u16
+// CHECK-LABEL: test_vmlsl_n_u16
 // CHECK: vmlsl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmlsl_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) {
   return vmlsl_n_u16(a, b, c);
 }
 
-// CHECK: test_vmlsl_n_u32
+// CHECK-LABEL: test_vmlsl_n_u32
 // CHECK: vmlsl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmlsl_n_u32(uint64x2_t a, uint32x2_t b, uint32_t c) {
   return vmlsl_n_u32(a, b, c);
 }
 
 
-// CHECK: test_vmls_lane_s16
+// CHECK-LABEL: test_vmls_lane_s16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vmls_lane_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vmls_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmls_lane_s32
+// CHECK-LABEL: test_vmls_lane_s32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vmls_lane_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vmls_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmls_lane_u16
+// CHECK-LABEL: test_vmls_lane_u16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x4_t test_vmls_lane_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmls_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmls_lane_u32
+// CHECK-LABEL: test_vmls_lane_u32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x2_t test_vmls_lane_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmls_lane_u32(a, b, c, 1);
 }
 
-// CHECK: test_vmls_lane_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmls_lane_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x2_t test_vmls_lane_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vmls_lane_f32(a, b, c, 1);
 }
 
-// CHECK: test_vmlsq_lane_s16
+// CHECK-LABEL: test_vmlsq_lane_s16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vmlsq_lane_s16(int16x8_t a, int16x8_t b, int16x4_t c) {
   return vmlsq_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmlsq_lane_s32
+// CHECK-LABEL: test_vmlsq_lane_s32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmlsq_lane_s32(int32x4_t a, int32x4_t b, int32x2_t c) {
   return vmlsq_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmlsq_lane_u16
+// CHECK-LABEL: test_vmlsq_lane_u16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x8_t test_vmlsq_lane_u16(uint16x8_t a, uint16x8_t b, uint16x4_t c) {
   return vmlsq_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmlsq_lane_u32
+// CHECK-LABEL: test_vmlsq_lane_u32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmlsq_lane_u32(uint32x4_t a, uint32x4_t b, uint32x2_t c) {
   return vmlsq_lane_u32(a, b, c, 1);
 }
 
-// CHECK: test_vmlsq_lane_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmlsq_lane_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x4_t test_vmlsq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t c) {
   return vmlsq_lane_f32(a, b, c, 1);
 }
 
 
-// CHECK: test_vmls_n_s16
+// CHECK-LABEL: test_vmls_n_s16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmls_n_s16(int16x4_t a, int16x4_t b, int16_t c) {
   return vmls_n_s16(a, b, c);
 }
 
-// CHECK: test_vmls_n_s32
+// CHECK-LABEL: test_vmls_n_s32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmls_n_s32(int32x2_t a, int32x2_t b, int32_t c) {
   return vmls_n_s32(a, b, c);
 }
 
-// CHECK: test_vmls_n_u16
+// CHECK-LABEL: test_vmls_n_u16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmls_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) {
   return vmls_n_u16(a, b, c);
 }
 
-// CHECK: test_vmls_n_u32
+// CHECK-LABEL: test_vmls_n_u32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmls_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) {
   return vmls_n_u32(a, b, c);
 }
 
-// CHECK: test_vmls_n_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmls_n_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmls_n_f32(float32x2_t a, float32x2_t b, float32_t c) {
   return vmls_n_f32(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_s16
+// CHECK-LABEL: test_vmlsq_n_s16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmlsq_n_s16(int16x8_t a, int16x8_t b, int16_t c) {
   return vmlsq_n_s16(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_s32
+// CHECK-LABEL: test_vmlsq_n_s32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmlsq_n_s32(int32x4_t a, int32x4_t b, int32_t c) {
   return vmlsq_n_s32(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_u16
+// CHECK-LABEL: test_vmlsq_n_u16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmlsq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) {
   return vmlsq_n_u16(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_u32
+// CHECK-LABEL: test_vmlsq_n_u32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmlsq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) {
   return vmlsq_n_u32(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmlsq_n_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmlsq_n_f32(float32x4_t a, float32x4_t b, float32_t c) {
   return vmlsq_n_f32(a, b, c);
 }
 
 
-// CHECK: test_vmovl_s8
+// CHECK-LABEL: test_vmovl_s8
 // CHECK: vmovl.s8 q{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vmovl_s8(int8x8_t a) {
   return vmovl_s8(a);
 }
 
-// CHECK: test_vmovl_s16
+// CHECK-LABEL: test_vmovl_s16
 // CHECK: vmovl.s16 q{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmovl_s16(int16x4_t a) {
   return vmovl_s16(a);
 }
 
-// CHECK: test_vmovl_s32
+// CHECK-LABEL: test_vmovl_s32
 // CHECK: vmovl.s32 q{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmovl_s32(int32x2_t a) {
   return vmovl_s32(a);
 }
 
-// CHECK: test_vmovl_u8
+// CHECK-LABEL: test_vmovl_u8
 // CHECK: vmovl.u8 q{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vmovl_u8(uint8x8_t a) {
   return vmovl_u8(a);
 }
 
-// CHECK: test_vmovl_u16
+// CHECK-LABEL: test_vmovl_u16
 // CHECK: vmovl.u16 q{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmovl_u16(uint16x4_t a) {
   return vmovl_u16(a);
 }
 
-// CHECK: test_vmovl_u32
+// CHECK-LABEL: test_vmovl_u32
 // CHECK: vmovl.u32 q{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmovl_u32(uint32x2_t a) {
   return vmovl_u32(a);
 }
 
 
-// CHECK: test_vmovn_s16
+// CHECK-LABEL: test_vmovn_s16
 // CHECK: vmovn.i16 d{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vmovn_s16(int16x8_t a) {
   return vmovn_s16(a);
 }
 
-// CHECK: test_vmovn_s32
+// CHECK-LABEL: test_vmovn_s32
 // CHECK: vmovn.i32 d{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vmovn_s32(int32x4_t a) {
   return vmovn_s32(a);
 }
 
-// CHECK: test_vmovn_s64
+// CHECK-LABEL: test_vmovn_s64
 // CHECK: vmovn.i64 d{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vmovn_s64(int64x2_t a) {
   return vmovn_s64(a);
 }
 
-// CHECK: test_vmovn_u16
+// CHECK-LABEL: test_vmovn_u16
 // CHECK: vmovn.i16 d{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vmovn_u16(uint16x8_t a) {
   return vmovn_u16(a);
 }
 
-// CHECK: test_vmovn_u32
+// CHECK-LABEL: test_vmovn_u32
 // CHECK: vmovn.i32 d{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vmovn_u32(uint32x4_t a) {
   return vmovn_u32(a);
 }
 
-// CHECK: test_vmovn_u64
+// CHECK-LABEL: test_vmovn_u64
 // CHECK: vmovn.i64 d{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vmovn_u64(uint64x2_t a) {
   return vmovn_u64(a);
 }
 
 
-// CHECK: test_vmov_n_u8
+// CHECK-LABEL: test_vmov_n_u8
 // CHECK: vmov 
 uint8x8_t test_vmov_n_u8(uint8_t a) {
   return vmov_n_u8(a);
 }
 
-// CHECK: test_vmov_n_u16
+// CHECK-LABEL: test_vmov_n_u16
 // CHECK: vmov 
 uint16x4_t test_vmov_n_u16(uint16_t a) {
   return vmov_n_u16(a);
 }
 
-// CHECK: test_vmov_n_u32
+// CHECK-LABEL: test_vmov_n_u32
 // CHECK: vmov 
 uint32x2_t test_vmov_n_u32(uint32_t a) {
   return vmov_n_u32(a);
 }
 
-// CHECK: test_vmov_n_s8
+// CHECK-LABEL: test_vmov_n_s8
 // CHECK: vmov 
 int8x8_t test_vmov_n_s8(int8_t a) {
   return vmov_n_s8(a);
 }
 
-// CHECK: test_vmov_n_s16
+// CHECK-LABEL: test_vmov_n_s16
 // CHECK: vmov 
 int16x4_t test_vmov_n_s16(int16_t a) {
   return vmov_n_s16(a);
 }
 
-// CHECK: test_vmov_n_s32
+// CHECK-LABEL: test_vmov_n_s32
 // CHECK: vmov 
 int32x2_t test_vmov_n_s32(int32_t a) {
   return vmov_n_s32(a);
 }
 
-// CHECK: test_vmov_n_p8
+// CHECK-LABEL: test_vmov_n_p8
 // CHECK: vmov 
 poly8x8_t test_vmov_n_p8(poly8_t a) {
   return vmov_n_p8(a);
 }
 
-// CHECK: test_vmov_n_p16
+// CHECK-LABEL: test_vmov_n_p16
 // CHECK: vmov 
 poly16x4_t test_vmov_n_p16(poly16_t a) {
   return vmov_n_p16(a);
 }
 
-// CHECK: test_vmov_n_f16
+// CHECK-LABEL: test_vmov_n_f16
 // CHECK: vld1.16 {{{d[0-9]+\[\]}}}
 float16x4_t test_vmov_n_f16(float16_t *a) {
   return vmov_n_f16(*a);
 }
 
-// CHECK: test_vmov_n_f32
+// CHECK-LABEL: test_vmov_n_f32
 // CHECK: vmov 
 float32x2_t test_vmov_n_f32(float32_t a) {
   return vmov_n_f32(a);
 }
 
-// CHECK: test_vmovq_n_u8
+// CHECK-LABEL: test_vmovq_n_u8
 // CHECK: vmov 
 uint8x16_t test_vmovq_n_u8(uint8_t a) {
   return vmovq_n_u8(a);
 }
 
-// CHECK: test_vmovq_n_u16
+// CHECK-LABEL: test_vmovq_n_u16
 // CHECK: vmov 
 uint16x8_t test_vmovq_n_u16(uint16_t a) {
   return vmovq_n_u16(a);
 }
 
-// CHECK: test_vmovq_n_u32
+// CHECK-LABEL: test_vmovq_n_u32
 // CHECK: vmov 
 uint32x4_t test_vmovq_n_u32(uint32_t a) {
   return vmovq_n_u32(a);
 }
 
-// CHECK: test_vmovq_n_s8
+// CHECK-LABEL: test_vmovq_n_s8
 // CHECK: vmov 
 int8x16_t test_vmovq_n_s8(int8_t a) {
   return vmovq_n_s8(a);
 }
 
-// CHECK: test_vmovq_n_s16
+// CHECK-LABEL: test_vmovq_n_s16
 // CHECK: vmov 
 int16x8_t test_vmovq_n_s16(int16_t a) {
   return vmovq_n_s16(a);
 }
 
-// CHECK: test_vmovq_n_s32
+// CHECK-LABEL: test_vmovq_n_s32
 // CHECK: vmov 
 int32x4_t test_vmovq_n_s32(int32_t a) {
   return vmovq_n_s32(a);
 }
 
-// CHECK: test_vmovq_n_p8
+// CHECK-LABEL: test_vmovq_n_p8
 // CHECK: vmov 
 poly8x16_t test_vmovq_n_p8(poly8_t a) {
   return vmovq_n_p8(a);
 }
 
-// CHECK: test_vmovq_n_p16
+// CHECK-LABEL: test_vmovq_n_p16
 // CHECK: vmov 
 poly16x8_t test_vmovq_n_p16(poly16_t a) {
   return vmovq_n_p16(a);
 }
 
-// CHECK: test_vmovq_n_f16
+// CHECK-LABEL: test_vmovq_n_f16
 // CHECK: vld1.16 {{{d[0-9]+\[\], d[0-9]+\[\]}}}
 float16x8_t test_vmovq_n_f16(float16_t *a) {
   return vmovq_n_f16(*a);
 }
 
-// CHECK: test_vmovq_n_f32
+// CHECK-LABEL: test_vmovq_n_f32
 // CHECK: vmov 
 float32x4_t test_vmovq_n_f32(float32_t a) {
   return vmovq_n_f32(a);
 }
 
-// CHECK: test_vmov_n_s64
+// CHECK-LABEL: test_vmov_n_s64
 // CHECK: vmov 
 int64x1_t test_vmov_n_s64(int64_t a) {
   return vmov_n_s64(a);
 }
 
-// CHECK: test_vmov_n_u64
+// CHECK-LABEL: test_vmov_n_u64
 // CHECK: vmov 
 uint64x1_t test_vmov_n_u64(uint64_t a) {
   return vmov_n_u64(a);
 }
 
-// CHECK: test_vmovq_n_s64
+// CHECK-LABEL: test_vmovq_n_s64
 // CHECK: vmov 
 int64x2_t test_vmovq_n_s64(int64_t a) {
   return vmovq_n_s64(a);
 }
 
-// CHECK: test_vmovq_n_u64
+// CHECK-LABEL: test_vmovq_n_u64
 // CHECK: vmov 
 uint64x2_t test_vmovq_n_u64(uint64_t a) {
   return vmovq_n_u64(a);
 }
 
 
-// CHECK: test_vmul_s8
+// CHECK-LABEL: test_vmul_s8
 // CHECK: vmul.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmul_s8(int8x8_t a, int8x8_t b) {
   return vmul_s8(a, b);
 }
 
-// CHECK: test_vmul_s16
+// CHECK-LABEL: test_vmul_s16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmul_s16(int16x4_t a, int16x4_t b) {
   return vmul_s16(a, b);
 }
 
-// CHECK: test_vmul_s32
+// CHECK-LABEL: test_vmul_s32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmul_s32(int32x2_t a, int32x2_t b) {
   return vmul_s32(a, b);
 }
 
-// CHECK: test_vmul_f32
+// CHECK-LABEL: test_vmul_f32
 // CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmul_f32(float32x2_t a, float32x2_t b) {
   return vmul_f32(a, b);
 }
 
-// CHECK: test_vmul_u8
+// CHECK-LABEL: test_vmul_u8
 // CHECK: vmul.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmul_u8(uint8x8_t a, uint8x8_t b) {
   return vmul_u8(a, b);
 }
 
-// CHECK: test_vmul_u16
+// CHECK-LABEL: test_vmul_u16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmul_u16(uint16x4_t a, uint16x4_t b) {
   return vmul_u16(a, b);
 }
 
-// CHECK: test_vmul_u32
+// CHECK-LABEL: test_vmul_u32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmul_u32(uint32x2_t a, uint32x2_t b) {
   return vmul_u32(a, b);
 }
 
-// CHECK: test_vmulq_s8
+// CHECK-LABEL: test_vmulq_s8
 // CHECK: vmul.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmulq_s8(int8x16_t a, int8x16_t b) {
   return vmulq_s8(a, b);
 }
 
-// CHECK: test_vmulq_s16
+// CHECK-LABEL: test_vmulq_s16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmulq_s16(int16x8_t a, int16x8_t b) {
   return vmulq_s16(a, b);
 }
 
-// CHECK: test_vmulq_s32
+// CHECK-LABEL: test_vmulq_s32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmulq_s32(int32x4_t a, int32x4_t b) {
   return vmulq_s32(a, b);
 }
 
-// CHECK: test_vmulq_f32
+// CHECK-LABEL: test_vmulq_f32
 // CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmulq_f32(float32x4_t a, float32x4_t b) {
   return vmulq_f32(a, b);
 }
 
-// CHECK: test_vmulq_u8
+// CHECK-LABEL: test_vmulq_u8
 // CHECK: vmul.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmulq_u8(uint8x16_t a, uint8x16_t b) {
   return vmulq_u8(a, b);
 }
 
-// CHECK: test_vmulq_u16
+// CHECK-LABEL: test_vmulq_u16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmulq_u16(uint16x8_t a, uint16x8_t b) {
   return vmulq_u16(a, b);
 }
 
-// CHECK: test_vmulq_u32
+// CHECK-LABEL: test_vmulq_u32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmulq_u32(uint32x4_t a, uint32x4_t b) {
   return vmulq_u32(a, b);
 }
 
 
-// CHECK: test_vmull_s8
+// CHECK-LABEL: test_vmull_s8
 // CHECK: vmull.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vmull_s8(int8x8_t a, int8x8_t b) {
   return vmull_s8(a, b);
 }
 
-// CHECK: test_vmull_s16
+// CHECK-LABEL: test_vmull_s16
 // CHECK: vmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmull_s16(int16x4_t a, int16x4_t b) {
   return vmull_s16(a, b);
 }
 
-// CHECK: test_vmull_s32
+// CHECK-LABEL: test_vmull_s32
 // CHECK: vmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmull_s32(int32x2_t a, int32x2_t b) {
   return vmull_s32(a, b);
 }
 
-// CHECK: test_vmull_u8
+// CHECK-LABEL: test_vmull_u8
 // CHECK: vmull.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vmull_u8(uint8x8_t a, uint8x8_t b) {
   return vmull_u8(a, b);
 }
 
-// CHECK: test_vmull_u16
+// CHECK-LABEL: test_vmull_u16
 // CHECK: vmull.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmull_u16(uint16x4_t a, uint16x4_t b) {
   return vmull_u16(a, b);
 }
 
-// CHECK: test_vmull_u32
+// CHECK-LABEL: test_vmull_u32
 // CHECK: vmull.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmull_u32(uint32x2_t a, uint32x2_t b) {
   return vmull_u32(a, b);
 }
 
-// CHECK: test_vmull_p8
+// CHECK-LABEL: test_vmull_p8
 // CHECK: vmull.p8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 poly16x8_t test_vmull_p8(poly8x8_t a, poly8x8_t b) {
   return vmull_p8(a, b);
 }
 
 
-// CHECK: test_vmull_lane_s16
+// CHECK-LABEL: test_vmull_lane_s16
 // CHECK: vmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmull_lane_s16(int16x4_t a, int16x4_t b) {
   return vmull_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vmull_lane_s32
+// CHECK-LABEL: test_vmull_lane_s32
 // CHECK: vmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vmull_lane_s32(int32x2_t a, int32x2_t b) {
   return vmull_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vmull_lane_u16
+// CHECK-LABEL: test_vmull_lane_u16
 // CHECK: vmull.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmull_lane_u16(uint16x4_t a, uint16x4_t b) {
   return vmull_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vmull_lane_u32
+// CHECK-LABEL: test_vmull_lane_u32
 // CHECK: vmull.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint64x2_t test_vmull_lane_u32(uint32x2_t a, uint32x2_t b) {
   return vmull_lane_u32(a, b, 1);
 }
 
 
-// CHECK: test_vmull_n_s16
+// CHECK-LABEL: test_vmull_n_s16
 // CHECK: vmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmull_n_s16(int16x4_t a, int16_t b) {
   return vmull_n_s16(a, b);
 }
 
-// CHECK: test_vmull_n_s32
+// CHECK-LABEL: test_vmull_n_s32
 // CHECK: vmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmull_n_s32(int32x2_t a, int32_t b) {
   return vmull_n_s32(a, b);
 }
 
-// CHECK: test_vmull_n_u16
+// CHECK-LABEL: test_vmull_n_u16
 // CHECK: vmull.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmull_n_u16(uint16x4_t a, uint16_t b) {
   return vmull_n_u16(a, b);
 }
 
-// CHECK: test_vmull_n_u32
+// CHECK-LABEL: test_vmull_n_u32
 // CHECK: vmull.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmull_n_u32(uint32x2_t a, uint32_t b) {
   return vmull_n_u32(a, b);
 }
 
 
-// CHECK: test_vmul_p8
+// CHECK-LABEL: test_vmul_p8
 // CHECK: vmul.p8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vmul_p8(poly8x8_t a, poly8x8_t b) {
   return vmul_p8(a, b);
 }
 
-// CHECK: test_vmulq_p8
+// CHECK-LABEL: test_vmulq_p8
 // CHECK: vmul.p8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vmulq_p8(poly8x16_t a, poly8x16_t b) {
   return vmulq_p8(a, b);
 }
 
 
-// CHECK: test_vmul_lane_s16
+// CHECK-LABEL: test_vmul_lane_s16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vmul_lane_s16(int16x4_t a, int16x4_t b) {
   return vmul_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vmul_lane_s32
+// CHECK-LABEL: test_vmul_lane_s32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vmul_lane_s32(int32x2_t a, int32x2_t b) {
   return vmul_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vmul_lane_f32
+// CHECK-LABEL: test_vmul_lane_f32
 // CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x2_t test_vmul_lane_f32(float32x2_t a, float32x2_t b) {
   return vmul_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vmul_lane_u16
+// CHECK-LABEL: test_vmul_lane_u16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x4_t test_vmul_lane_u16(uint16x4_t a, uint16x4_t b) {
   return vmul_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vmul_lane_u32
+// CHECK-LABEL: test_vmul_lane_u32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x2_t test_vmul_lane_u32(uint32x2_t a, uint32x2_t b) {
   return vmul_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vmulq_lane_s16
+// CHECK-LABEL: test_vmulq_lane_s16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vmulq_lane_s16(int16x8_t a, int16x4_t b) {
   return vmulq_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vmulq_lane_s32
+// CHECK-LABEL: test_vmulq_lane_s32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmulq_lane_s32(int32x4_t a, int32x2_t b) {
   return vmulq_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vmulq_lane_f32
+// CHECK-LABEL: test_vmulq_lane_f32
 // CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x4_t test_vmulq_lane_f32(float32x4_t a, float32x2_t b) {
   return vmulq_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vmulq_lane_u16
+// CHECK-LABEL: test_vmulq_lane_u16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x8_t test_vmulq_lane_u16(uint16x8_t a, uint16x4_t b) {
   return vmulq_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vmulq_lane_u32
+// CHECK-LABEL: test_vmulq_lane_u32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmulq_lane_u32(uint32x4_t a, uint32x2_t b) {
   return vmulq_lane_u32(a, b, 1);
 }
 
 
-// CHECK: test_vmul_n_s16
+// CHECK-LABEL: test_vmul_n_s16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmul_n_s16(int16x4_t a, int16_t b) {
   return vmul_n_s16(a, b);
 }
 
-// CHECK: test_vmul_n_s32
+// CHECK-LABEL: test_vmul_n_s32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmul_n_s32(int32x2_t a, int32_t b) {
   return vmul_n_s32(a, b);
 }
 
-// CHECK: test_vmul_n_f32
+// CHECK-LABEL: test_vmul_n_f32
 // CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmul_n_f32(float32x2_t a, float32_t b) {
   return vmul_n_f32(a, b);
 }
 
-// CHECK: test_vmul_n_u16
+// CHECK-LABEL: test_vmul_n_u16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmul_n_u16(uint16x4_t a, uint16_t b) {
   return vmul_n_u16(a, b);
 }
 
-// CHECK: test_vmul_n_u32
+// CHECK-LABEL: test_vmul_n_u32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmul_n_u32(uint32x2_t a, uint32_t b) {
   return vmul_n_u32(a, b);
 }
 
-// CHECK: test_vmulq_n_s16
+// CHECK-LABEL: test_vmulq_n_s16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmulq_n_s16(int16x8_t a, int16_t b) {
   return vmulq_n_s16(a, b);
 }
 
-// CHECK: test_vmulq_n_s32
+// CHECK-LABEL: test_vmulq_n_s32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmulq_n_s32(int32x4_t a, int32_t b) {
   return vmulq_n_s32(a, b);
 }
 
-// CHECK: test_vmulq_n_f32
+// CHECK-LABEL: test_vmulq_n_f32
 // CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
 float32x4_t test_vmulq_n_f32(float32x4_t a, float32_t b) {
   return vmulq_n_f32(a, b);
 }
 
-// CHECK: test_vmulq_n_u16
+// CHECK-LABEL: test_vmulq_n_u16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmulq_n_u16(uint16x8_t a, uint16_t b) {
   return vmulq_n_u16(a, b);
 }
 
-// CHECK: test_vmulq_n_u32
+// CHECK-LABEL: test_vmulq_n_u32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmulq_n_u32(uint32x4_t a, uint32_t b) {
   return vmulq_n_u32(a, b);
 }
 
 
-// CHECK: test_vmvn_s8
+// CHECK-LABEL: test_vmvn_s8
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmvn_s8(int8x8_t a) {
   return vmvn_s8(a);
 }
 
-// CHECK: test_vmvn_s16
+// CHECK-LABEL: test_vmvn_s16
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmvn_s16(int16x4_t a) {
   return vmvn_s16(a);
 }
 
-// CHECK: test_vmvn_s32
+// CHECK-LABEL: test_vmvn_s32
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmvn_s32(int32x2_t a) {
   return vmvn_s32(a);
 }
 
-// CHECK: test_vmvn_u8
+// CHECK-LABEL: test_vmvn_u8
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmvn_u8(uint8x8_t a) {
   return vmvn_u8(a);
 }
 
-// CHECK: test_vmvn_u16
+// CHECK-LABEL: test_vmvn_u16
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmvn_u16(uint16x4_t a) {
   return vmvn_u16(a);
 }
 
-// CHECK: test_vmvn_u32
+// CHECK-LABEL: test_vmvn_u32
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmvn_u32(uint32x2_t a) {
   return vmvn_u32(a);
 }
 
-// CHECK: test_vmvn_p8
+// CHECK-LABEL: test_vmvn_p8
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vmvn_p8(poly8x8_t a) {
   return vmvn_p8(a);
 }
 
-// CHECK: test_vmvnq_s8
+// CHECK-LABEL: test_vmvnq_s8
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmvnq_s8(int8x16_t a) {
   return vmvnq_s8(a);
 }
 
-// CHECK: test_vmvnq_s16
+// CHECK-LABEL: test_vmvnq_s16
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmvnq_s16(int16x8_t a) {
   return vmvnq_s16(a);
 }
 
-// CHECK: test_vmvnq_s32
+// CHECK-LABEL: test_vmvnq_s32
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmvnq_s32(int32x4_t a) {
   return vmvnq_s32(a);
 }
 
-// CHECK: test_vmvnq_u8
+// CHECK-LABEL: test_vmvnq_u8
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmvnq_u8(uint8x16_t a) {
   return vmvnq_u8(a);
 }
 
-// CHECK: test_vmvnq_u16
+// CHECK-LABEL: test_vmvnq_u16
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmvnq_u16(uint16x8_t a) {
   return vmvnq_u16(a);
 }
 
-// CHECK: test_vmvnq_u32
+// CHECK-LABEL: test_vmvnq_u32
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmvnq_u32(uint32x4_t a) {
   return vmvnq_u32(a);
 }
 
-// CHECK: test_vmvnq_p8
+// CHECK-LABEL: test_vmvnq_p8
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vmvnq_p8(poly8x16_t a) {
   return vmvnq_p8(a);
 }
 
 
-// CHECK: test_vneg_s8
+// CHECK-LABEL: test_vneg_s8
 // CHECK: vneg.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vneg_s8(int8x8_t a) {
   return vneg_s8(a);
 }
 
-// CHECK: test_vneg_s16
+// CHECK-LABEL: test_vneg_s16
 // CHECK: vneg.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vneg_s16(int16x4_t a) {
   return vneg_s16(a);
 }
 
-// CHECK: test_vneg_s32
+// CHECK-LABEL: test_vneg_s32
 // CHECK: vneg.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vneg_s32(int32x2_t a) {
   return vneg_s32(a);
 }
 
-// CHECK: test_vneg_f32
+// CHECK-LABEL: test_vneg_f32
 // CHECK: vneg.f32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vneg_f32(float32x2_t a) {
   return vneg_f32(a);
 }
 
-// CHECK: test_vnegq_s8
+// CHECK-LABEL: test_vnegq_s8
 // CHECK: vneg.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vnegq_s8(int8x16_t a) {
   return vnegq_s8(a);
 }
 
-// CHECK: test_vnegq_s16
+// CHECK-LABEL: test_vnegq_s16
 // CHECK: vneg.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vnegq_s16(int16x8_t a) {
   return vnegq_s16(a);
 }
 
-// CHECK: test_vnegq_s32
+// CHECK-LABEL: test_vnegq_s32
 // CHECK: vneg.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vnegq_s32(int32x4_t a) {
   return vnegq_s32(a);
 }
 
-// CHECK: test_vnegq_f32
+// CHECK-LABEL: test_vnegq_f32
 // CHECK: vneg.f32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vnegq_f32(float32x4_t a) {
   return vnegq_f32(a);
 }
 
 
-// CHECK: test_vorn_s8
+// CHECK-LABEL: test_vorn_s8
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vorn_s8(int8x8_t a, int8x8_t b) {
   return vorn_s8(a, b);
 }
 
-// CHECK: test_vorn_s16
+// CHECK-LABEL: test_vorn_s16
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vorn_s16(int16x4_t a, int16x4_t b) {
   return vorn_s16(a, b);
 }
 
-// CHECK: test_vorn_s32
+// CHECK-LABEL: test_vorn_s32
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vorn_s32(int32x2_t a, int32x2_t b) {
   return vorn_s32(a, b);
 }
 
-// CHECK: test_vorn_s64
+// CHECK-LABEL: test_vorn_s64
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vorn_s64(int64x1_t a, int64x1_t b) {
   return vorn_s64(a, b);
 }
 
-// CHECK: test_vorn_u8
+// CHECK-LABEL: test_vorn_u8
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vorn_u8(uint8x8_t a, uint8x8_t b) {
   return vorn_u8(a, b);
 }
 
-// CHECK: test_vorn_u16
+// CHECK-LABEL: test_vorn_u16
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vorn_u16(uint16x4_t a, uint16x4_t b) {
   return vorn_u16(a, b);
 }
 
-// CHECK: test_vorn_u32
+// CHECK-LABEL: test_vorn_u32
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vorn_u32(uint32x2_t a, uint32x2_t b) {
   return vorn_u32(a, b);
 }
 
-// CHECK: test_vorn_u64
+// CHECK-LABEL: test_vorn_u64
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vorn_u64(uint64x1_t a, uint64x1_t b) {
   return vorn_u64(a, b);
 }
 
-// CHECK: test_vornq_s8
+// CHECK-LABEL: test_vornq_s8
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vornq_s8(int8x16_t a, int8x16_t b) {
   return vornq_s8(a, b);
 }
 
-// CHECK: test_vornq_s16
+// CHECK-LABEL: test_vornq_s16
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vornq_s16(int16x8_t a, int16x8_t b) {
   return vornq_s16(a, b);
 }
 
-// CHECK: test_vornq_s32
+// CHECK-LABEL: test_vornq_s32
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vornq_s32(int32x4_t a, int32x4_t b) {
   return vornq_s32(a, b);
 }
 
-// CHECK: test_vornq_s64
+// CHECK-LABEL: test_vornq_s64
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vornq_s64(int64x2_t a, int64x2_t b) {
   return vornq_s64(a, b);
 }
 
-// CHECK: test_vornq_u8
+// CHECK-LABEL: test_vornq_u8
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vornq_u8(uint8x16_t a, uint8x16_t b) {
   return vornq_u8(a, b);
 }
 
-// CHECK: test_vornq_u16
+// CHECK-LABEL: test_vornq_u16
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vornq_u16(uint16x8_t a, uint16x8_t b) {
   return vornq_u16(a, b);
 }
 
-// CHECK: test_vornq_u32
+// CHECK-LABEL: test_vornq_u32
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vornq_u32(uint32x4_t a, uint32x4_t b) {
   return vornq_u32(a, b);
 }
 
-// CHECK: test_vornq_u64
+// CHECK-LABEL: test_vornq_u64
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vornq_u64(uint64x2_t a, uint64x2_t b) {
   return vornq_u64(a, b);
 }
 
 
-// CHECK: test_vorr_s8
+// CHECK-LABEL: test_vorr_s8
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vorr_s8(int8x8_t a, int8x8_t b) {
   return vorr_s8(a, b);
 }
 
-// CHECK: test_vorr_s16
+// CHECK-LABEL: test_vorr_s16
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vorr_s16(int16x4_t a, int16x4_t b) {
   return vorr_s16(a, b);
 }
 
-// CHECK: test_vorr_s32
+// CHECK-LABEL: test_vorr_s32
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vorr_s32(int32x2_t a, int32x2_t b) {
   return vorr_s32(a, b);
 }
 
-// CHECK: test_vorr_s64
+// CHECK-LABEL: test_vorr_s64
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vorr_s64(int64x1_t a, int64x1_t b) {
   return vorr_s64(a, b);
 }
 
-// CHECK: test_vorr_u8
+// CHECK-LABEL: test_vorr_u8
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vorr_u8(uint8x8_t a, uint8x8_t b) {
   return vorr_u8(a, b);
 }
 
-// CHECK: test_vorr_u16
+// CHECK-LABEL: test_vorr_u16
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vorr_u16(uint16x4_t a, uint16x4_t b) {
   return vorr_u16(a, b);
 }
 
-// CHECK: test_vorr_u32
+// CHECK-LABEL: test_vorr_u32
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vorr_u32(uint32x2_t a, uint32x2_t b) {
   return vorr_u32(a, b);
 }
 
-// CHECK: test_vorr_u64
+// CHECK-LABEL: test_vorr_u64
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vorr_u64(uint64x1_t a, uint64x1_t b) {
   return vorr_u64(a, b);
 }
 
-// CHECK: test_vorrq_s8
+// CHECK-LABEL: test_vorrq_s8
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vorrq_s8(int8x16_t a, int8x16_t b) {
   return vorrq_s8(a, b);
 }
 
-// CHECK: test_vorrq_s16
+// CHECK-LABEL: test_vorrq_s16
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vorrq_s16(int16x8_t a, int16x8_t b) {
   return vorrq_s16(a, b);
 }
 
-// CHECK: test_vorrq_s32
+// CHECK-LABEL: test_vorrq_s32
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vorrq_s32(int32x4_t a, int32x4_t b) {
   return vorrq_s32(a, b);
 }
 
-// CHECK: test_vorrq_s64
+// CHECK-LABEL: test_vorrq_s64
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vorrq_s64(int64x2_t a, int64x2_t b) {
   return vorrq_s64(a, b);
 }
 
-// CHECK: test_vorrq_u8
+// CHECK-LABEL: test_vorrq_u8
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vorrq_u8(uint8x16_t a, uint8x16_t b) {
   return vorrq_u8(a, b);
 }
 
-// CHECK: test_vorrq_u16
+// CHECK-LABEL: test_vorrq_u16
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vorrq_u16(uint16x8_t a, uint16x8_t b) {
   return vorrq_u16(a, b);
 }
 
-// CHECK: test_vorrq_u32
+// CHECK-LABEL: test_vorrq_u32
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vorrq_u32(uint32x4_t a, uint32x4_t b) {
   return vorrq_u32(a, b);
 }
 
-// CHECK: test_vorrq_u64
+// CHECK-LABEL: test_vorrq_u64
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vorrq_u64(uint64x2_t a, uint64x2_t b) {
   return vorrq_u64(a, b);
 }
 
 
-// CHECK: test_vpadal_s8
+// CHECK-LABEL: test_vpadal_s8
 // CHECK: vpadal.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpadal_s8(int16x4_t a, int8x8_t b) {
   return vpadal_s8(a, b);
 }
 
-// CHECK: test_vpadal_s16
+// CHECK-LABEL: test_vpadal_s16
 // CHECK: vpadal.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpadal_s16(int32x2_t a, int16x4_t b) {
   return vpadal_s16(a, b);
 }
 
-// CHECK: test_vpadal_s32
+// CHECK-LABEL: test_vpadal_s32
 // CHECK: vpadal.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vpadal_s32(int64x1_t a, int32x2_t b) {
   return vpadal_s32(a, b);
 }
 
-// CHECK: test_vpadal_u8
+// CHECK-LABEL: test_vpadal_u8
 // CHECK: vpadal.u8 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpadal_u8(uint16x4_t a, uint8x8_t b) {
   return vpadal_u8(a, b);
 }
 
-// CHECK: test_vpadal_u16
+// CHECK-LABEL: test_vpadal_u16
 // CHECK: vpadal.u16 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpadal_u16(uint32x2_t a, uint16x4_t b) {
   return vpadal_u16(a, b);
 }
 
-// CHECK: test_vpadal_u32
+// CHECK-LABEL: test_vpadal_u32
 // CHECK: vpadal.u32 d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vpadal_u32(uint64x1_t a, uint32x2_t b) {
   return vpadal_u32(a, b);
 }
 
-// CHECK: test_vpadalq_s8
+// CHECK-LABEL: test_vpadalq_s8
 // CHECK: vpadal.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vpadalq_s8(int16x8_t a, int8x16_t b) {
   return vpadalq_s8(a, b);
 }
 
-// CHECK: test_vpadalq_s16
+// CHECK-LABEL: test_vpadalq_s16
 // CHECK: vpadal.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vpadalq_s16(int32x4_t a, int16x8_t b) {
   return vpadalq_s16(a, b);
 }
 
-// CHECK: test_vpadalq_s32
+// CHECK-LABEL: test_vpadalq_s32
 // CHECK: vpadal.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vpadalq_s32(int64x2_t a, int32x4_t b) {
   return vpadalq_s32(a, b);
 }
 
-// CHECK: test_vpadalq_u8
+// CHECK-LABEL: test_vpadalq_u8
 // CHECK: vpadal.u8 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vpadalq_u8(uint16x8_t a, uint8x16_t b) {
   return vpadalq_u8(a, b);
 }
 
-// CHECK: test_vpadalq_u16
+// CHECK-LABEL: test_vpadalq_u16
 // CHECK: vpadal.u16 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vpadalq_u16(uint32x4_t a, uint16x8_t b) {
   return vpadalq_u16(a, b);
 }
 
-// CHECK: test_vpadalq_u32
+// CHECK-LABEL: test_vpadalq_u32
 // CHECK: vpadal.u32 q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vpadalq_u32(uint64x2_t a, uint32x4_t b) {
   return vpadalq_u32(a, b);
 }
 
 
-// CHECK: test_vpadd_s8
+// CHECK-LABEL: test_vpadd_s8
 // CHECK: vpadd.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vpadd_s8(int8x8_t a, int8x8_t b) {
   return vpadd_s8(a, b);
 }
 
-// CHECK: test_vpadd_s16
+// CHECK-LABEL: test_vpadd_s16
 // CHECK: vpadd.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpadd_s16(int16x4_t a, int16x4_t b) {
   return vpadd_s16(a, b);
 }
 
-// CHECK: test_vpadd_s32
+// CHECK-LABEL: test_vpadd_s32
 // CHECK: vpadd.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpadd_s32(int32x2_t a, int32x2_t b) {
   return vpadd_s32(a, b);
 }
 
-// CHECK: test_vpadd_u8
+// CHECK-LABEL: test_vpadd_u8
 // CHECK: vpadd.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vpadd_u8(uint8x8_t a, uint8x8_t b) {
   return vpadd_u8(a, b);
 }
 
-// CHECK: test_vpadd_u16
+// CHECK-LABEL: test_vpadd_u16
 // CHECK: vpadd.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpadd_u16(uint16x4_t a, uint16x4_t b) {
   return vpadd_u16(a, b);
 }
 
-// CHECK: test_vpadd_u32
+// CHECK-LABEL: test_vpadd_u32
 // CHECK: vpadd.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpadd_u32(uint32x2_t a, uint32x2_t b) {
   return vpadd_u32(a, b);
 }
 
-// CHECK: test_vpadd_f32
+// CHECK-LABEL: test_vpadd_f32
 // CHECK: vpadd.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vpadd_f32(float32x2_t a, float32x2_t b) {
   return vpadd_f32(a, b);
 }
 
 
-// CHECK: test_vpaddl_s8
+// CHECK-LABEL: test_vpaddl_s8
 // CHECK: vpaddl.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpaddl_s8(int8x8_t a) {
   return vpaddl_s8(a);
 }
 
-// CHECK: test_vpaddl_s16
+// CHECK-LABEL: test_vpaddl_s16
 // CHECK: vpaddl.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpaddl_s16(int16x4_t a) {
   return vpaddl_s16(a);
 }
 
-// CHECK: test_vpaddl_s32
+// CHECK-LABEL: test_vpaddl_s32
 // CHECK: vpaddl.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vpaddl_s32(int32x2_t a) {
   return vpaddl_s32(a);
 }
 
-// CHECK: test_vpaddl_u8
+// CHECK-LABEL: test_vpaddl_u8
 // CHECK: vpaddl.u8 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpaddl_u8(uint8x8_t a) {
   return vpaddl_u8(a);
 }
 
-// CHECK: test_vpaddl_u16
+// CHECK-LABEL: test_vpaddl_u16
 // CHECK: vpaddl.u16 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpaddl_u16(uint16x4_t a) {
   return vpaddl_u16(a);
 }
 
-// CHECK: test_vpaddl_u32
+// CHECK-LABEL: test_vpaddl_u32
 // CHECK: vpaddl.u32 d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vpaddl_u32(uint32x2_t a) {
   return vpaddl_u32(a);
 }
 
-// CHECK: test_vpaddlq_s8
+// CHECK-LABEL: test_vpaddlq_s8
 // CHECK: vpaddl.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vpaddlq_s8(int8x16_t a) {
   return vpaddlq_s8(a);
 }
 
-// CHECK: test_vpaddlq_s16
+// CHECK-LABEL: test_vpaddlq_s16
 // CHECK: vpaddl.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vpaddlq_s16(int16x8_t a) {
   return vpaddlq_s16(a);
 }
 
-// CHECK: test_vpaddlq_s32
+// CHECK-LABEL: test_vpaddlq_s32
 // CHECK: vpaddl.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vpaddlq_s32(int32x4_t a) {
   return vpaddlq_s32(a);
 }
 
-// CHECK: test_vpaddlq_u8
+// CHECK-LABEL: test_vpaddlq_u8
 // CHECK: vpaddl.u8 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vpaddlq_u8(uint8x16_t a) {
   return vpaddlq_u8(a);
 }
 
-// CHECK: test_vpaddlq_u16
+// CHECK-LABEL: test_vpaddlq_u16
 // CHECK: vpaddl.u16 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vpaddlq_u16(uint16x8_t a) {
   return vpaddlq_u16(a);
 }
 
-// CHECK: test_vpaddlq_u32
+// CHECK-LABEL: test_vpaddlq_u32
 // CHECK: vpaddl.u32 q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vpaddlq_u32(uint32x4_t a) {
   return vpaddlq_u32(a);
 }
 
 
-// CHECK: test_vpmax_s8
+// CHECK-LABEL: test_vpmax_s8
 // CHECK: vpmax.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vpmax_s8(int8x8_t a, int8x8_t b) {
   return vpmax_s8(a, b);
 }
 
-// CHECK: test_vpmax_s16
+// CHECK-LABEL: test_vpmax_s16
 // CHECK: vpmax.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpmax_s16(int16x4_t a, int16x4_t b) {
   return vpmax_s16(a, b);
 }
 
-// CHECK: test_vpmax_s32
+// CHECK-LABEL: test_vpmax_s32
 // CHECK: vpmax.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpmax_s32(int32x2_t a, int32x2_t b) {
   return vpmax_s32(a, b);
 }
 
-// CHECK: test_vpmax_u8
+// CHECK-LABEL: test_vpmax_u8
 // CHECK: vpmax.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vpmax_u8(uint8x8_t a, uint8x8_t b) {
   return vpmax_u8(a, b);
 }
 
-// CHECK: test_vpmax_u16
+// CHECK-LABEL: test_vpmax_u16
 // CHECK: vpmax.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpmax_u16(uint16x4_t a, uint16x4_t b) {
   return vpmax_u16(a, b);
 }
 
-// CHECK: test_vpmax_u32
+// CHECK-LABEL: test_vpmax_u32
 // CHECK: vpmax.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpmax_u32(uint32x2_t a, uint32x2_t b) {
   return vpmax_u32(a, b);
 }
 
-// CHECK: test_vpmax_f32
+// CHECK-LABEL: test_vpmax_f32
 // CHECK: vpmax.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vpmax_f32(float32x2_t a, float32x2_t b) {
   return vpmax_f32(a, b);
 }
 
 
-// CHECK: test_vpmin_s8
+// CHECK-LABEL: test_vpmin_s8
 // CHECK: vpmin.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vpmin_s8(int8x8_t a, int8x8_t b) {
   return vpmin_s8(a, b);
 }
 
-// CHECK: test_vpmin_s16
+// CHECK-LABEL: test_vpmin_s16
 // CHECK: vpmin.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpmin_s16(int16x4_t a, int16x4_t b) {
   return vpmin_s16(a, b);
 }
 
-// CHECK: test_vpmin_s32
+// CHECK-LABEL: test_vpmin_s32
 // CHECK: vpmin.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpmin_s32(int32x2_t a, int32x2_t b) {
   return vpmin_s32(a, b);
 }
 
-// CHECK: test_vpmin_u8
+// CHECK-LABEL: test_vpmin_u8
 // CHECK: vpmin.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vpmin_u8(uint8x8_t a, uint8x8_t b) {
   return vpmin_u8(a, b);
 }
 
-// CHECK: test_vpmin_u16
+// CHECK-LABEL: test_vpmin_u16
 // CHECK: vpmin.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpmin_u16(uint16x4_t a, uint16x4_t b) {
   return vpmin_u16(a, b);
 }
 
-// CHECK: test_vpmin_u32
+// CHECK-LABEL: test_vpmin_u32
 // CHECK: vpmin.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpmin_u32(uint32x2_t a, uint32x2_t b) {
   return vpmin_u32(a, b);
 }
 
-// CHECK: test_vpmin_f32
+// CHECK-LABEL: test_vpmin_f32
 // CHECK: vpmin.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vpmin_f32(float32x2_t a, float32x2_t b) {
   return vpmin_f32(a, b);
 }
 
 
-// CHECK: test_vqabs_s8
+// CHECK-LABEL: test_vqabs_s8
 // CHECK: vqabs.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqabs_s8(int8x8_t a) {
   return vqabs_s8(a);
 }
 
-// CHECK: test_vqabs_s16
+// CHECK-LABEL: test_vqabs_s16
 // CHECK: vqabs.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqabs_s16(int16x4_t a) {
   return vqabs_s16(a);
 }
 
-// CHECK: test_vqabs_s32
+// CHECK-LABEL: test_vqabs_s32
 // CHECK: vqabs.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqabs_s32(int32x2_t a) {
   return vqabs_s32(a);
 }
 
-// CHECK: test_vqabsq_s8
+// CHECK-LABEL: test_vqabsq_s8
 // CHECK: vqabs.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqabsq_s8(int8x16_t a) {
   return vqabsq_s8(a);
 }
 
-// CHECK: test_vqabsq_s16
+// CHECK-LABEL: test_vqabsq_s16
 // CHECK: vqabs.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqabsq_s16(int16x8_t a) {
   return vqabsq_s16(a);
 }
 
-// CHECK: test_vqabsq_s32
+// CHECK-LABEL: test_vqabsq_s32
 // CHECK: vqabs.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqabsq_s32(int32x4_t a) {
   return vqabsq_s32(a);
 }
 
 
-// CHECK: test_vqadd_s8
+// CHECK-LABEL: test_vqadd_s8
 // CHECK: vqadd.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqadd_s8(int8x8_t a, int8x8_t b) {
   return vqadd_s8(a, b);
 }
 
-// CHECK: test_vqadd_s16
+// CHECK-LABEL: test_vqadd_s16
 // CHECK: vqadd.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqadd_s16(int16x4_t a, int16x4_t b) {
   return vqadd_s16(a, b);
 }
 
-// CHECK: test_vqadd_s32
+// CHECK-LABEL: test_vqadd_s32
 // CHECK: vqadd.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqadd_s32(int32x2_t a, int32x2_t b) {
   return vqadd_s32(a, b);
 }
 
-// CHECK: test_vqadd_s64
+// CHECK-LABEL: test_vqadd_s64
 // CHECK: vqadd.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vqadd_s64(int64x1_t a, int64x1_t b) {
   return vqadd_s64(a, b);
 }
 
-// CHECK: test_vqadd_u8
+// CHECK-LABEL: test_vqadd_u8
 // CHECK: vqadd.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vqadd_u8(uint8x8_t a, uint8x8_t b) {
   return vqadd_u8(a, b);
 }
 
-// CHECK: test_vqadd_u16
+// CHECK-LABEL: test_vqadd_u16
 // CHECK: vqadd.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vqadd_u16(uint16x4_t a, uint16x4_t b) {
   return vqadd_u16(a, b);
 }
 
-// CHECK: test_vqadd_u32
+// CHECK-LABEL: test_vqadd_u32
 // CHECK: vqadd.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vqadd_u32(uint32x2_t a, uint32x2_t b) {
   return vqadd_u32(a, b);
 }
 
-// CHECK: test_vqadd_u64
+// CHECK-LABEL: test_vqadd_u64
 // CHECK: vqadd.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vqadd_u64(uint64x1_t a, uint64x1_t b) {
   return vqadd_u64(a, b);
 }
 
-// CHECK: test_vqaddq_s8
+// CHECK-LABEL: test_vqaddq_s8
 // CHECK: vqadd.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqaddq_s8(int8x16_t a, int8x16_t b) {
   return vqaddq_s8(a, b);
 }
 
-// CHECK: test_vqaddq_s16
+// CHECK-LABEL: test_vqaddq_s16
 // CHECK: vqadd.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqaddq_s16(int16x8_t a, int16x8_t b) {
   return vqaddq_s16(a, b);
 }
 
-// CHECK: test_vqaddq_s32
+// CHECK-LABEL: test_vqaddq_s32
 // CHECK: vqadd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqaddq_s32(int32x4_t a, int32x4_t b) {
   return vqaddq_s32(a, b);
 }
 
-// CHECK: test_vqaddq_s64
+// CHECK-LABEL: test_vqaddq_s64
 // CHECK: vqadd.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vqaddq_s64(int64x2_t a, int64x2_t b) {
   return vqaddq_s64(a, b);
 }
 
-// CHECK: test_vqaddq_u8
+// CHECK-LABEL: test_vqaddq_u8
 // CHECK: vqadd.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vqaddq_u8(uint8x16_t a, uint8x16_t b) {
   return vqaddq_u8(a, b);
 }
 
-// CHECK: test_vqaddq_u16
+// CHECK-LABEL: test_vqaddq_u16
 // CHECK: vqadd.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vqaddq_u16(uint16x8_t a, uint16x8_t b) {
   return vqaddq_u16(a, b);
 }
 
-// CHECK: test_vqaddq_u32
+// CHECK-LABEL: test_vqaddq_u32
 // CHECK: vqadd.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vqaddq_u32(uint32x4_t a, uint32x4_t b) {
   return vqaddq_u32(a, b);
 }
 
-// CHECK: test_vqaddq_u64
+// CHECK-LABEL: test_vqaddq_u64
 // CHECK: vqadd.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vqaddq_u64(uint64x2_t a, uint64x2_t b) {
   return vqaddq_u64(a, b);
 }
 
 
-// CHECK: test_vqdmlal_s16
+// CHECK-LABEL: test_vqdmlal_s16
 // CHECK: vqdmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmlal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vqdmlal_s16(a, b, c);
 }
 
-// CHECK: test_vqdmlal_s32
+// CHECK-LABEL: test_vqdmlal_s32
 // CHECK: vqdmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmlal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vqdmlal_s32(a, b, c);
 }
 
 
-// CHECK: test_vqdmlal_lane_s16
+// CHECK-LABEL: test_vqdmlal_lane_s16
 // CHECK: vqdmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqdmlal_lane_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vqdmlal_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vqdmlal_lane_s32
+// CHECK-LABEL: test_vqdmlal_lane_s32
 // CHECK: vqdmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vqdmlal_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vqdmlal_lane_s32(a, b, c, 1);
 }
 
 
-// CHECK: test_vqdmlal_n_s16
+// CHECK-LABEL: test_vqdmlal_n_s16
 // CHECK: vqdmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
   return vqdmlal_n_s16(a, b, c);
 }
 
-// CHECK: test_vqdmlal_n_s32
+// CHECK-LABEL: test_vqdmlal_n_s32
 // CHECK: vqdmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
   return vqdmlal_n_s32(a, b, c);
 }
 
 
-// CHECK: test_vqdmlsl_s16
+// CHECK-LABEL: test_vqdmlsl_s16
 // CHECK: vqdmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmlsl_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vqdmlsl_s16(a, b, c);
 }
 
-// CHECK: test_vqdmlsl_s32
+// CHECK-LABEL: test_vqdmlsl_s32
 // CHECK: vqdmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmlsl_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vqdmlsl_s32(a, b, c);
 }
 
 
-// CHECK: test_vqdmlsl_lane_s16
+// CHECK-LABEL: test_vqdmlsl_lane_s16
 // CHECK: vqdmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqdmlsl_lane_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vqdmlsl_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vqdmlsl_lane_s32
+// CHECK-LABEL: test_vqdmlsl_lane_s32
 // CHECK: vqdmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vqdmlsl_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vqdmlsl_lane_s32(a, b, c, 1);
 }
 
 
-// CHECK: test_vqdmlsl_n_s16
+// CHECK-LABEL: test_vqdmlsl_n_s16
 // CHECK: vqdmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
   return vqdmlsl_n_s16(a, b, c);
 }
 
-// CHECK: test_vqdmlsl_n_s32
+// CHECK-LABEL: test_vqdmlsl_n_s32
 // CHECK: vqdmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmlsl_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
   return vqdmlsl_n_s32(a, b, c);
 }
 
 
-// CHECK: test_vqdmulh_s16
+// CHECK-LABEL: test_vqdmulh_s16
 // CHECK: vqdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqdmulh_s16(int16x4_t a, int16x4_t b) {
   return vqdmulh_s16(a, b);
 }
 
-// CHECK: test_vqdmulh_s32
+// CHECK-LABEL: test_vqdmulh_s32
 // CHECK: vqdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqdmulh_s32(int32x2_t a, int32x2_t b) {
   return vqdmulh_s32(a, b);
 }
 
-// CHECK: test_vqdmulhq_s16
+// CHECK-LABEL: test_vqdmulhq_s16
 // CHECK: vqdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqdmulhq_s16(int16x8_t a, int16x8_t b) {
   return vqdmulhq_s16(a, b);
 }
 
-// CHECK: test_vqdmulhq_s32
+// CHECK-LABEL: test_vqdmulhq_s32
 // CHECK: vqdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqdmulhq_s32(int32x4_t a, int32x4_t b) {
   return vqdmulhq_s32(a, b);
 }
 
 
-// CHECK: test_vqdmulh_lane_s16
+// CHECK-LABEL: test_vqdmulh_lane_s16
 // CHECK: vqdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vqdmulh_lane_s16(int16x4_t a, int16x4_t b) {
   return vqdmulh_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqdmulh_lane_s32
+// CHECK-LABEL: test_vqdmulh_lane_s32
 // CHECK: vqdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vqdmulh_lane_s32(int32x2_t a, int32x2_t b) {
   return vqdmulh_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vqdmulhq_lane_s16
+// CHECK-LABEL: test_vqdmulhq_lane_s16
 // CHECK: vqdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vqdmulhq_lane_s16(int16x8_t a, int16x4_t b) {
   return vqdmulhq_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqdmulhq_lane_s32
+// CHECK-LABEL: test_vqdmulhq_lane_s32
 // CHECK: vqdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqdmulhq_lane_s32(int32x4_t a, int32x2_t b) {
   return vqdmulhq_lane_s32(a, b, 1);
 }
 
 
-// CHECK: test_vqdmulh_n_s16
+// CHECK-LABEL: test_vqdmulh_n_s16
 // CHECK: vqdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqdmulh_n_s16(int16x4_t a, int16_t b) {
   return vqdmulh_n_s16(a, b);
 }
 
-// CHECK: test_vqdmulh_n_s32
+// CHECK-LABEL: test_vqdmulh_n_s32
 // CHECK: vqdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqdmulh_n_s32(int32x2_t a, int32_t b) {
   return vqdmulh_n_s32(a, b);
 }
 
-// CHECK: test_vqdmulhq_n_s16
+// CHECK-LABEL: test_vqdmulhq_n_s16
 // CHECK: vqdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqdmulhq_n_s16(int16x8_t a, int16_t b) {
   return vqdmulhq_n_s16(a, b);
 }
 
-// CHECK: test_vqdmulhq_n_s32
+// CHECK-LABEL: test_vqdmulhq_n_s32
 // CHECK: vqdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqdmulhq_n_s32(int32x4_t a, int32_t b) {
   return vqdmulhq_n_s32(a, b);
 }
 
 
-// CHECK: test_vqdmull_s16
+// CHECK-LABEL: test_vqdmull_s16
 // CHECK: vqdmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmull_s16(int16x4_t a, int16x4_t b) {
   return vqdmull_s16(a, b);
 }
 
-// CHECK: test_vqdmull_s32
+// CHECK-LABEL: test_vqdmull_s32
 // CHECK: vqdmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmull_s32(int32x2_t a, int32x2_t b) {
   return vqdmull_s32(a, b);
 }
 
 
-// CHECK: test_vqdmull_lane_s16
+// CHECK-LABEL: test_vqdmull_lane_s16
 // CHECK: vqdmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqdmull_lane_s16(int16x4_t a, int16x4_t b) {
   return vqdmull_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqdmull_lane_s32
+// CHECK-LABEL: test_vqdmull_lane_s32
 // CHECK: vqdmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vqdmull_lane_s32(int32x2_t a, int32x2_t b) {
   return vqdmull_lane_s32(a, b, 1);
 }
 
 
-// CHECK: test_vqdmull_n_s16
+// CHECK-LABEL: test_vqdmull_n_s16
 // CHECK: vqdmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmull_n_s16(int16x4_t a, int16_t b) {
   return vqdmull_n_s16(a, b);
 }
 
-// CHECK: test_vqdmull_n_s32
+// CHECK-LABEL: test_vqdmull_n_s32
 // CHECK: vqdmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmull_n_s32(int32x2_t a, int32_t b) {
   return vqdmull_n_s32(a, b);
 }
 
 
-// CHECK: test_vqmovn_s16
+// CHECK-LABEL: test_vqmovn_s16
 // CHECK: vqmovn.s16 d{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vqmovn_s16(int16x8_t a) {
   return vqmovn_s16(a);
 }
 
-// CHECK: test_vqmovn_s32
+// CHECK-LABEL: test_vqmovn_s32
 // CHECK: vqmovn.s32 d{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vqmovn_s32(int32x4_t a) {
   return vqmovn_s32(a);
 }
 
-// CHECK: test_vqmovn_s64
+// CHECK-LABEL: test_vqmovn_s64
 // CHECK: vqmovn.s64 d{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vqmovn_s64(int64x2_t a) {
   return vqmovn_s64(a);
 }
 
-// CHECK: test_vqmovn_u16
+// CHECK-LABEL: test_vqmovn_u16
 // CHECK: vqmovn.u16 d{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vqmovn_u16(uint16x8_t a) {
   return vqmovn_u16(a);
 }
 
-// CHECK: test_vqmovn_u32
+// CHECK-LABEL: test_vqmovn_u32
 // CHECK: vqmovn.u32 d{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vqmovn_u32(uint32x4_t a) {
   return vqmovn_u32(a);
 }
 
-// CHECK: test_vqmovn_u64
+// CHECK-LABEL: test_vqmovn_u64
 // CHECK: vqmovn.u64 d{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vqmovn_u64(uint64x2_t a) {
   return vqmovn_u64(a);
 }
 
 
-// CHECK: test_vqmovun_s16
+// CHECK-LABEL: test_vqmovun_s16
 // CHECK: vqmovun.s16 d{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vqmovun_s16(int16x8_t a) {
   return vqmovun_s16(a);
 }
 
-// CHECK: test_vqmovun_s32
+// CHECK-LABEL: test_vqmovun_s32
 // CHECK: vqmovun.s32 d{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vqmovun_s32(int32x4_t a) {
   return vqmovun_s32(a);
 }
 
-// CHECK: test_vqmovun_s64
+// CHECK-LABEL: test_vqmovun_s64
 // CHECK: vqmovun.s64 d{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vqmovun_s64(int64x2_t a) {
   return vqmovun_s64(a);
 }
 
 
-// CHECK: test_vqneg_s8
+// CHECK-LABEL: test_vqneg_s8
 // CHECK: vqneg.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqneg_s8(int8x8_t a) {
   return vqneg_s8(a);
 }
 
-// CHECK: test_vqneg_s16
+// CHECK-LABEL: test_vqneg_s16
 // CHECK: vqneg.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqneg_s16(int16x4_t a) {
   return vqneg_s16(a);
 }
 
-// CHECK: test_vqneg_s32
+// CHECK-LABEL: test_vqneg_s32
 // CHECK: vqneg.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqneg_s32(int32x2_t a) {
   return vqneg_s32(a);
 }
 
-// CHECK: test_vqnegq_s8
+// CHECK-LABEL: test_vqnegq_s8
 // CHECK: vqneg.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqnegq_s8(int8x16_t a) {
   return vqnegq_s8(a);
 }
 
-// CHECK: test_vqnegq_s16
+// CHECK-LABEL: test_vqnegq_s16
 // CHECK: vqneg.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqnegq_s16(int16x8_t a) {
   return vqnegq_s16(a);
 }
 
-// CHECK: test_vqnegq_s32
+// CHECK-LABEL: test_vqnegq_s32
 // CHECK: vqneg.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqnegq_s32(int32x4_t a) {
   return vqnegq_s32(a);
 }
 
 
-// CHECK: test_vqrdmulh_s16
+// CHECK-LABEL: test_vqrdmulh_s16
 // CHECK: vqrdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqrdmulh_s16(int16x4_t a, int16x4_t b) {
   return vqrdmulh_s16(a, b);
 }
 
-// CHECK: test_vqrdmulh_s32
+// CHECK-LABEL: test_vqrdmulh_s32
 // CHECK: vqrdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqrdmulh_s32(int32x2_t a, int32x2_t b) {
   return vqrdmulh_s32(a, b);
 }
 
-// CHECK: test_vqrdmulhq_s16
+// CHECK-LABEL: test_vqrdmulhq_s16
 // CHECK: vqrdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqrdmulhq_s16(int16x8_t a, int16x8_t b) {
   return vqrdmulhq_s16(a, b);
 }
 
-// CHECK: test_vqrdmulhq_s32
+// CHECK-LABEL: test_vqrdmulhq_s32
 // CHECK: vqrdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqrdmulhq_s32(int32x4_t a, int32x4_t b) {
   return vqrdmulhq_s32(a, b);
 }
 
 
-// CHECK: test_vqrdmulh_lane_s16
+// CHECK-LABEL: test_vqrdmulh_lane_s16
 // CHECK: vqrdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vqrdmulh_lane_s16(int16x4_t a, int16x4_t b) {
   return vqrdmulh_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqrdmulh_lane_s32
+// CHECK-LABEL: test_vqrdmulh_lane_s32
 // CHECK: vqrdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vqrdmulh_lane_s32(int32x2_t a, int32x2_t b) {
   return vqrdmulh_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vqrdmulhq_lane_s16
+// CHECK-LABEL: test_vqrdmulhq_lane_s16
 // CHECK: vqrdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vqrdmulhq_lane_s16(int16x8_t a, int16x4_t b) {
   return vqrdmulhq_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqrdmulhq_lane_s32
+// CHECK-LABEL: test_vqrdmulhq_lane_s32
 // CHECK: vqrdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqrdmulhq_lane_s32(int32x4_t a, int32x2_t b) {
   return vqrdmulhq_lane_s32(a, b, 1);
 }
 
 
-// CHECK: test_vqrdmulh_n_s16
+// CHECK-LABEL: test_vqrdmulh_n_s16
 // CHECK: vqrdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqrdmulh_n_s16(int16x4_t a, int16_t b) {
   return vqrdmulh_n_s16(a, b);
 }
 
-// CHECK: test_vqrdmulh_n_s32
+// CHECK-LABEL: test_vqrdmulh_n_s32
 // CHECK: vqrdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqrdmulh_n_s32(int32x2_t a, int32_t b) {
   return vqrdmulh_n_s32(a, b);
 }
 
-// CHECK: test_vqrdmulhq_n_s16
+// CHECK-LABEL: test_vqrdmulhq_n_s16
 // CHECK: vqrdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqrdmulhq_n_s16(int16x8_t a, int16_t b) {
   return vqrdmulhq_n_s16(a, b);
 }
 
-// CHECK: test_vqrdmulhq_n_s32
+// CHECK-LABEL: test_vqrdmulhq_n_s32
 // CHECK: vqrdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqrdmulhq_n_s32(int32x4_t a, int32_t b) {
   return vqrdmulhq_n_s32(a, b);
 }
 
 
-// CHECK: test_vqrshl_s8
+// CHECK-LABEL: test_vqrshl_s8
 // CHECK: vqrshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqrshl_s8(int8x8_t a, int8x8_t b) {
   return vqrshl_s8(a, b);
 }
 
-// CHECK: test_vqrshl_s16
+// CHECK-LABEL: test_vqrshl_s16
 // CHECK: vqrshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqrshl_s16(int16x4_t a, int16x4_t b) {
   return vqrshl_s16(a, b);
 }
 
-// CHECK: test_vqrshl_s32
+// CHECK-LABEL: test_vqrshl_s32
 // CHECK: vqrshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqrshl_s32(int32x2_t a, int32x2_t b) {
   return vqrshl_s32(a, b);
 }
 
-// CHECK: test_vqrshl_s64
+// CHECK-LABEL: test_vqrshl_s64
 // CHECK: vqrshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vqrshl_s64(int64x1_t a, int64x1_t b) {
   return vqrshl_s64(a, b);
 }
 
-// CHECK: test_vqrshl_u8
+// CHECK-LABEL: test_vqrshl_u8
 // CHECK: vqrshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vqrshl_u8(uint8x8_t a, int8x8_t b) {
   return vqrshl_u8(a, b);
 }
 
-// CHECK: test_vqrshl_u16
+// CHECK-LABEL: test_vqrshl_u16
 // CHECK: vqrshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vqrshl_u16(uint16x4_t a, int16x4_t b) {
   return vqrshl_u16(a, b);
 }
 
-// CHECK: test_vqrshl_u32
+// CHECK-LABEL: test_vqrshl_u32
 // CHECK: vqrshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vqrshl_u32(uint32x2_t a, int32x2_t b) {
   return vqrshl_u32(a, b);
 }
 
-// CHECK: test_vqrshl_u64
+// CHECK-LABEL: test_vqrshl_u64
 // CHECK: vqrshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vqrshl_u64(uint64x1_t a, int64x1_t b) {
   return vqrshl_u64(a, b);
 }
 
-// CHECK: test_vqrshlq_s8
+// CHECK-LABEL: test_vqrshlq_s8
 // CHECK: vqrshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqrshlq_s8(int8x16_t a, int8x16_t b) {
   return vqrshlq_s8(a, b);
 }
 
-// CHECK: test_vqrshlq_s16
+// CHECK-LABEL: test_vqrshlq_s16
 // CHECK: vqrshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqrshlq_s16(int16x8_t a, int16x8_t b) {
   return vqrshlq_s16(a, b);
 }
 
-// CHECK: test_vqrshlq_s32
+// CHECK-LABEL: test_vqrshlq_s32
 // CHECK: vqrshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqrshlq_s32(int32x4_t a, int32x4_t b) {
   return vqrshlq_s32(a, b);
 }
 
-// CHECK: test_vqrshlq_s64
+// CHECK-LABEL: test_vqrshlq_s64
 // CHECK: vqrshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vqrshlq_s64(int64x2_t a, int64x2_t b) {
   return vqrshlq_s64(a, b);
 }
 
-// CHECK: test_vqrshlq_u8
+// CHECK-LABEL: test_vqrshlq_u8
 // CHECK: vqrshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vqrshlq_u8(uint8x16_t a, int8x16_t b) {
   return vqrshlq_u8(a, b);
 }
 
-// CHECK: test_vqrshlq_u16
+// CHECK-LABEL: test_vqrshlq_u16
 // CHECK: vqrshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vqrshlq_u16(uint16x8_t a, int16x8_t b) {
   return vqrshlq_u16(a, b);
 }
 
-// CHECK: test_vqrshlq_u32
+// CHECK-LABEL: test_vqrshlq_u32
 // CHECK: vqrshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vqrshlq_u32(uint32x4_t a, int32x4_t b) {
   return vqrshlq_u32(a, b);
 }
 
-// CHECK: test_vqrshlq_u64
+// CHECK-LABEL: test_vqrshlq_u64
 // CHECK: vqrshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vqrshlq_u64(uint64x2_t a, int64x2_t b) {
   return vqrshlq_u64(a, b);
 }
 
 
-// CHECK: test_vqrshrn_n_s16
+// CHECK-LABEL: test_vqrshrn_n_s16
 // CHECK: vqrshrn.s16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vqrshrn_n_s16(int16x8_t a) {
   return vqrshrn_n_s16(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_s32
+// CHECK-LABEL: test_vqrshrn_n_s32
 // CHECK: vqrshrn.s32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vqrshrn_n_s32(int32x4_t a) {
   return vqrshrn_n_s32(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_s64
+// CHECK-LABEL: test_vqrshrn_n_s64
 // CHECK: vqrshrn.s64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vqrshrn_n_s64(int64x2_t a) {
   return vqrshrn_n_s64(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_u16
+// CHECK-LABEL: test_vqrshrn_n_u16
 // CHECK: vqrshrn.u16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqrshrn_n_u16(uint16x8_t a) {
   return vqrshrn_n_u16(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_u32
+// CHECK-LABEL: test_vqrshrn_n_u32
 // CHECK: vqrshrn.u32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqrshrn_n_u32(uint32x4_t a) {
   return vqrshrn_n_u32(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_u64
+// CHECK-LABEL: test_vqrshrn_n_u64
 // CHECK: vqrshrn.u64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqrshrn_n_u64(uint64x2_t a) {
   return vqrshrn_n_u64(a, 1);
 }
 
 
-// CHECK: test_vqrshrun_n_s16
+// CHECK-LABEL: test_vqrshrun_n_s16
 // CHECK: vqrshrun.s16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqrshrun_n_s16(int16x8_t a) {
   return vqrshrun_n_s16(a, 1);
 }
 
-// CHECK: test_vqrshrun_n_s32
+// CHECK-LABEL: test_vqrshrun_n_s32
 // CHECK: vqrshrun.s32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqrshrun_n_s32(int32x4_t a) {
   return vqrshrun_n_s32(a, 1);
 }
 
-// CHECK: test_vqrshrun_n_s64
+// CHECK-LABEL: test_vqrshrun_n_s64
 // CHECK: vqrshrun.s64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqrshrun_n_s64(int64x2_t a) {
   return vqrshrun_n_s64(a, 1);
 }
 
 
-// CHECK: test_vqshl_s8
+// CHECK-LABEL: test_vqshl_s8
 // CHECK: vqshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqshl_s8(int8x8_t a, int8x8_t b) {
   return vqshl_s8(a, b);
 }
 
-// CHECK: test_vqshl_s16
+// CHECK-LABEL: test_vqshl_s16
 // CHECK: vqshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqshl_s16(int16x4_t a, int16x4_t b) {
   return vqshl_s16(a, b);
 }
 
-// CHECK: test_vqshl_s32
+// CHECK-LABEL: test_vqshl_s32
 // CHECK: vqshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqshl_s32(int32x2_t a, int32x2_t b) {
   return vqshl_s32(a, b);
 }
 
-// CHECK: test_vqshl_s64
+// CHECK-LABEL: test_vqshl_s64
 // CHECK: vqshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vqshl_s64(int64x1_t a, int64x1_t b) {
   return vqshl_s64(a, b);
 }
 
-// CHECK: test_vqshl_u8
+// CHECK-LABEL: test_vqshl_u8
 // CHECK: vqshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vqshl_u8(uint8x8_t a, int8x8_t b) {
   return vqshl_u8(a, b);
 }
 
-// CHECK: test_vqshl_u16
+// CHECK-LABEL: test_vqshl_u16
 // CHECK: vqshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vqshl_u16(uint16x4_t a, int16x4_t b) {
   return vqshl_u16(a, b);
 }
 
-// CHECK: test_vqshl_u32
+// CHECK-LABEL: test_vqshl_u32
 // CHECK: vqshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vqshl_u32(uint32x2_t a, int32x2_t b) {
   return vqshl_u32(a, b);
 }
 
-// CHECK: test_vqshl_u64
+// CHECK-LABEL: test_vqshl_u64
 // CHECK: vqshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vqshl_u64(uint64x1_t a, int64x1_t b) {
   return vqshl_u64(a, b);
 }
 
-// CHECK: test_vqshlq_s8
+// CHECK-LABEL: test_vqshlq_s8
 // CHECK: vqshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqshlq_s8(int8x16_t a, int8x16_t b) {
   return vqshlq_s8(a, b);
 }
 
-// CHECK: test_vqshlq_s16
+// CHECK-LABEL: test_vqshlq_s16
 // CHECK: vqshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqshlq_s16(int16x8_t a, int16x8_t b) {
   return vqshlq_s16(a, b);
 }
 
-// CHECK: test_vqshlq_s32
+// CHECK-LABEL: test_vqshlq_s32
 // CHECK: vqshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqshlq_s32(int32x4_t a, int32x4_t b) {
   return vqshlq_s32(a, b);
 }
 
-// CHECK: test_vqshlq_s64
+// CHECK-LABEL: test_vqshlq_s64
 // CHECK: vqshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vqshlq_s64(int64x2_t a, int64x2_t b) {
   return vqshlq_s64(a, b);
 }
 
-// CHECK: test_vqshlq_u8
+// CHECK-LABEL: test_vqshlq_u8
 // CHECK: vqshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vqshlq_u8(uint8x16_t a, int8x16_t b) {
   return vqshlq_u8(a, b);
 }
 
-// CHECK: test_vqshlq_u16
+// CHECK-LABEL: test_vqshlq_u16
 // CHECK: vqshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vqshlq_u16(uint16x8_t a, int16x8_t b) {
   return vqshlq_u16(a, b);
 }
 
-// CHECK: test_vqshlq_u32
+// CHECK-LABEL: test_vqshlq_u32
 // CHECK: vqshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vqshlq_u32(uint32x4_t a, int32x4_t b) {
   return vqshlq_u32(a, b);
 }
 
-// CHECK: test_vqshlq_u64
+// CHECK-LABEL: test_vqshlq_u64
 // CHECK: vqshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vqshlq_u64(uint64x2_t a, int64x2_t b) {
   return vqshlq_u64(a, b);
 }
 
 
-// CHECK: test_vqshlu_n_s8
+// CHECK-LABEL: test_vqshlu_n_s8
 // CHECK: vqshlu.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqshlu_n_s8(int8x8_t a) {
   return vqshlu_n_s8(a, 1);
 }
 
-// CHECK: test_vqshlu_n_s16
+// CHECK-LABEL: test_vqshlu_n_s16
 // CHECK: vqshlu.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqshlu_n_s16(int16x4_t a) {
   return vqshlu_n_s16(a, 1);
 }
 
-// CHECK: test_vqshlu_n_s32
+// CHECK-LABEL: test_vqshlu_n_s32
 // CHECK: vqshlu.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqshlu_n_s32(int32x2_t a) {
   return vqshlu_n_s32(a, 1);
 }
 
-// CHECK: test_vqshlu_n_s64
+// CHECK-LABEL: test_vqshlu_n_s64
 // CHECK: vqshlu.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vqshlu_n_s64(int64x1_t a) {
   return vqshlu_n_s64(a, 1);
 }
 
-// CHECK: test_vqshluq_n_s8
+// CHECK-LABEL: test_vqshluq_n_s8
 // CHECK: vqshlu.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vqshluq_n_s8(int8x16_t a) {
   return vqshluq_n_s8(a, 1);
 }
 
-// CHECK: test_vqshluq_n_s16
+// CHECK-LABEL: test_vqshluq_n_s16
 // CHECK: vqshlu.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vqshluq_n_s16(int16x8_t a) {
   return vqshluq_n_s16(a, 1);
 }
 
-// CHECK: test_vqshluq_n_s32
+// CHECK-LABEL: test_vqshluq_n_s32
 // CHECK: vqshlu.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vqshluq_n_s32(int32x4_t a) {
   return vqshluq_n_s32(a, 1);
 }
 
-// CHECK: test_vqshluq_n_s64
+// CHECK-LABEL: test_vqshluq_n_s64
 // CHECK: vqshlu.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vqshluq_n_s64(int64x2_t a) {
   return vqshluq_n_s64(a, 1);
 }
 
 
-// CHECK: test_vqshl_n_s8
+// CHECK-LABEL: test_vqshl_n_s8
 // CHECK: vqshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vqshl_n_s8(int8x8_t a) {
   return vqshl_n_s8(a, 1);
 }
 
-// CHECK: test_vqshl_n_s16
+// CHECK-LABEL: test_vqshl_n_s16
 // CHECK: vqshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vqshl_n_s16(int16x4_t a) {
   return vqshl_n_s16(a, 1);
 }
 
-// CHECK: test_vqshl_n_s32
+// CHECK-LABEL: test_vqshl_n_s32
 // CHECK: vqshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vqshl_n_s32(int32x2_t a) {
   return vqshl_n_s32(a, 1);
 }
 
-// CHECK: test_vqshl_n_s64
+// CHECK-LABEL: test_vqshl_n_s64
 // CHECK: vqshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vqshl_n_s64(int64x1_t a) {
   return vqshl_n_s64(a, 1);
 }
 
-// CHECK: test_vqshl_n_u8
+// CHECK-LABEL: test_vqshl_n_u8
 // CHECK: vqshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqshl_n_u8(uint8x8_t a) {
   return vqshl_n_u8(a, 1);
 }
 
-// CHECK: test_vqshl_n_u16
+// CHECK-LABEL: test_vqshl_n_u16
 // CHECK: vqshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqshl_n_u16(uint16x4_t a) {
   return vqshl_n_u16(a, 1);
 }
 
-// CHECK: test_vqshl_n_u32
+// CHECK-LABEL: test_vqshl_n_u32
 // CHECK: vqshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqshl_n_u32(uint32x2_t a) {
   return vqshl_n_u32(a, 1);
 }
 
-// CHECK: test_vqshl_n_u64
+// CHECK-LABEL: test_vqshl_n_u64
 // CHECK: vqshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vqshl_n_u64(uint64x1_t a) {
   return vqshl_n_u64(a, 1);
 }
 
-// CHECK: test_vqshlq_n_s8
+// CHECK-LABEL: test_vqshlq_n_s8
 // CHECK: vqshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vqshlq_n_s8(int8x16_t a) {
   return vqshlq_n_s8(a, 1);
 }
 
-// CHECK: test_vqshlq_n_s16
+// CHECK-LABEL: test_vqshlq_n_s16
 // CHECK: vqshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vqshlq_n_s16(int16x8_t a) {
   return vqshlq_n_s16(a, 1);
 }
 
-// CHECK: test_vqshlq_n_s32
+// CHECK-LABEL: test_vqshlq_n_s32
 // CHECK: vqshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vqshlq_n_s32(int32x4_t a) {
   return vqshlq_n_s32(a, 1);
 }
 
-// CHECK: test_vqshlq_n_s64
+// CHECK-LABEL: test_vqshlq_n_s64
 // CHECK: vqshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vqshlq_n_s64(int64x2_t a) {
   return vqshlq_n_s64(a, 1);
 }
 
-// CHECK: test_vqshlq_n_u8
+// CHECK-LABEL: test_vqshlq_n_u8
 // CHECK: vqshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vqshlq_n_u8(uint8x16_t a) {
   return vqshlq_n_u8(a, 1);
 }
 
-// CHECK: test_vqshlq_n_u16
+// CHECK-LABEL: test_vqshlq_n_u16
 // CHECK: vqshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vqshlq_n_u16(uint16x8_t a) {
   return vqshlq_n_u16(a, 1);
 }
 
-// CHECK: test_vqshlq_n_u32
+// CHECK-LABEL: test_vqshlq_n_u32
 // CHECK: vqshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vqshlq_n_u32(uint32x4_t a) {
   return vqshlq_n_u32(a, 1);
 }
 
-// CHECK: test_vqshlq_n_u64
+// CHECK-LABEL: test_vqshlq_n_u64
 // CHECK: vqshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vqshlq_n_u64(uint64x2_t a) {
   return vqshlq_n_u64(a, 1);
 }
 
 
-// CHECK: test_vqshrn_n_s16
+// CHECK-LABEL: test_vqshrn_n_s16
 // CHECK: vqshrn.s16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vqshrn_n_s16(int16x8_t a) {
   return vqshrn_n_s16(a, 1);
 }
 
-// CHECK: test_vqshrn_n_s32
+// CHECK-LABEL: test_vqshrn_n_s32
 // CHECK: vqshrn.s32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vqshrn_n_s32(int32x4_t a) {
   return vqshrn_n_s32(a, 1);
 }
 
-// CHECK: test_vqshrn_n_s64
+// CHECK-LABEL: test_vqshrn_n_s64
 // CHECK: vqshrn.s64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vqshrn_n_s64(int64x2_t a) {
   return vqshrn_n_s64(a, 1);
 }
 
-// CHECK: test_vqshrn_n_u16
+// CHECK-LABEL: test_vqshrn_n_u16
 // CHECK: vqshrn.u16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqshrn_n_u16(uint16x8_t a) {
   return vqshrn_n_u16(a, 1);
 }
 
-// CHECK: test_vqshrn_n_u32
+// CHECK-LABEL: test_vqshrn_n_u32
 // CHECK: vqshrn.u32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqshrn_n_u32(uint32x4_t a) {
   return vqshrn_n_u32(a, 1);
 }
 
-// CHECK: test_vqshrn_n_u64
+// CHECK-LABEL: test_vqshrn_n_u64
 // CHECK: vqshrn.u64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqshrn_n_u64(uint64x2_t a) {
   return vqshrn_n_u64(a, 1);
 }
 
 
-// CHECK: test_vqshrun_n_s16
+// CHECK-LABEL: test_vqshrun_n_s16
 // CHECK: vqshrun.s16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqshrun_n_s16(int16x8_t a) {
   return vqshrun_n_s16(a, 1);
 }
 
-// CHECK: test_vqshrun_n_s32
+// CHECK-LABEL: test_vqshrun_n_s32
 // CHECK: vqshrun.s32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqshrun_n_s32(int32x4_t a) {
   return vqshrun_n_s32(a, 1);
 }
 
-// CHECK: test_vqshrun_n_s64
+// CHECK-LABEL: test_vqshrun_n_s64
 // CHECK: vqshrun.s64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqshrun_n_s64(int64x2_t a) {
   return vqshrun_n_s64(a, 1);
 }
 
 
-// CHECK: test_vqsub_s8
+// CHECK-LABEL: test_vqsub_s8
 // CHECK: vqsub.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqsub_s8(int8x8_t a, int8x8_t b) {
   return vqsub_s8(a, b);
 }
 
-// CHECK: test_vqsub_s16
+// CHECK-LABEL: test_vqsub_s16
 // CHECK: vqsub.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqsub_s16(int16x4_t a, int16x4_t b) {
   return vqsub_s16(a, b);
 }
 
-// CHECK: test_vqsub_s32
+// CHECK-LABEL: test_vqsub_s32
 // CHECK: vqsub.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqsub_s32(int32x2_t a, int32x2_t b) {
   return vqsub_s32(a, b);
 }
 
-// CHECK: test_vqsub_s64
+// CHECK-LABEL: test_vqsub_s64
 // CHECK: vqsub.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vqsub_s64(int64x1_t a, int64x1_t b) {
   return vqsub_s64(a, b);
 }
 
-// CHECK: test_vqsub_u8
+// CHECK-LABEL: test_vqsub_u8
 // CHECK: vqsub.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vqsub_u8(uint8x8_t a, uint8x8_t b) {
   return vqsub_u8(a, b);
 }
 
-// CHECK: test_vqsub_u16
+// CHECK-LABEL: test_vqsub_u16
 // CHECK: vqsub.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vqsub_u16(uint16x4_t a, uint16x4_t b) {
   return vqsub_u16(a, b);
 }
 
-// CHECK: test_vqsub_u32
+// CHECK-LABEL: test_vqsub_u32
 // CHECK: vqsub.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vqsub_u32(uint32x2_t a, uint32x2_t b) {
   return vqsub_u32(a, b);
 }
 
-// CHECK: test_vqsub_u64
+// CHECK-LABEL: test_vqsub_u64
 // CHECK: vqsub.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vqsub_u64(uint64x1_t a, uint64x1_t b) {
   return vqsub_u64(a, b);
 }
 
-// CHECK: test_vqsubq_s8
+// CHECK-LABEL: test_vqsubq_s8
 // CHECK: vqsub.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqsubq_s8(int8x16_t a, int8x16_t b) {
   return vqsubq_s8(a, b);
 }
 
-// CHECK: test_vqsubq_s16
+// CHECK-LABEL: test_vqsubq_s16
 // CHECK: vqsub.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqsubq_s16(int16x8_t a, int16x8_t b) {
   return vqsubq_s16(a, b);
 }
 
-// CHECK: test_vqsubq_s32
+// CHECK-LABEL: test_vqsubq_s32
 // CHECK: vqsub.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqsubq_s32(int32x4_t a, int32x4_t b) {
   return vqsubq_s32(a, b);
 }
 
-// CHECK: test_vqsubq_s64
+// CHECK-LABEL: test_vqsubq_s64
 // CHECK: vqsub.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vqsubq_s64(int64x2_t a, int64x2_t b) {
   return vqsubq_s64(a, b);
 }
 
-// CHECK: test_vqsubq_u8
+// CHECK-LABEL: test_vqsubq_u8
 // CHECK: vqsub.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vqsubq_u8(uint8x16_t a, uint8x16_t b) {
   return vqsubq_u8(a, b);
 }
 
-// CHECK: test_vqsubq_u16
+// CHECK-LABEL: test_vqsubq_u16
 // CHECK: vqsub.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vqsubq_u16(uint16x8_t a, uint16x8_t b) {
   return vqsubq_u16(a, b);
 }
 
-// CHECK: test_vqsubq_u32
+// CHECK-LABEL: test_vqsubq_u32
 // CHECK: vqsub.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vqsubq_u32(uint32x4_t a, uint32x4_t b) {
   return vqsubq_u32(a, b);
 }
 
-// CHECK: test_vqsubq_u64
+// CHECK-LABEL: test_vqsubq_u64
 // CHECK: vqsub.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vqsubq_u64(uint64x2_t a, uint64x2_t b) {
   return vqsubq_u64(a, b);
 }
 
 
-// CHECK: test_vraddhn_s16
+// CHECK-LABEL: test_vraddhn_s16
 // CHECK: vraddhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vraddhn_s16(int16x8_t a, int16x8_t b) {
   return vraddhn_s16(a, b);
 }
 
-// CHECK: test_vraddhn_s32
+// CHECK-LABEL: test_vraddhn_s32
 // CHECK: vraddhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vraddhn_s32(int32x4_t a, int32x4_t b) {
   return vraddhn_s32(a, b);
 }
 
-// CHECK: test_vraddhn_s64
+// CHECK-LABEL: test_vraddhn_s64
 // CHECK: vraddhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vraddhn_s64(int64x2_t a, int64x2_t b) {
   return vraddhn_s64(a, b);
 }
 
-// CHECK: test_vraddhn_u16
+// CHECK-LABEL: test_vraddhn_u16
 // CHECK: vraddhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vraddhn_u16(uint16x8_t a, uint16x8_t b) {
   return vraddhn_u16(a, b);
 }
 
-// CHECK: test_vraddhn_u32
+// CHECK-LABEL: test_vraddhn_u32
 // CHECK: vraddhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vraddhn_u32(uint32x4_t a, uint32x4_t b) {
   return vraddhn_u32(a, b);
 }
 
-// CHECK: test_vraddhn_u64
+// CHECK-LABEL: test_vraddhn_u64
 // CHECK: vraddhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vraddhn_u64(uint64x2_t a, uint64x2_t b) {
   return vraddhn_u64(a, b);
 }
 
 
-// CHECK: test_vrecpe_f32
+// CHECK-LABEL: test_vrecpe_f32
 // CHECK: vrecpe.f32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrecpe_f32(float32x2_t a) {
   return vrecpe_f32(a);
 }
 
-// CHECK: test_vrecpe_u32
+// CHECK-LABEL: test_vrecpe_u32
 // CHECK: vrecpe.u32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrecpe_u32(uint32x2_t a) {
   return vrecpe_u32(a);
 }
 
-// CHECK: test_vrecpeq_f32
+// CHECK-LABEL: test_vrecpeq_f32
 // CHECK: vrecpe.f32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrecpeq_f32(float32x4_t a) {
   return vrecpeq_f32(a);
 }
 
-// CHECK: test_vrecpeq_u32
+// CHECK-LABEL: test_vrecpeq_u32
 // CHECK: vrecpe.u32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrecpeq_u32(uint32x4_t a) {
   return vrecpeq_u32(a);
 }
 
 
-// CHECK: test_vrecps_f32
+// CHECK-LABEL: test_vrecps_f32
 // CHECK: vrecps.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrecps_f32(float32x2_t a, float32x2_t b) {
   return vrecps_f32(a, b);
 }
 
-// CHECK: test_vrecpsq_f32
+// CHECK-LABEL: test_vrecpsq_f32
 // CHECK: vrecps.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrecpsq_f32(float32x4_t a, float32x4_t b) {
   return vrecpsq_f32(a, b);
 }
 
 
-// CHECK: test_vreinterpret_s8_s16
+// CHECK-LABEL: test_vreinterpret_s8_s16
 int8x8_t test_vreinterpret_s8_s16(int16x4_t a) {
   return vreinterpret_s8_s16(a);
 }
 
-// CHECK: test_vreinterpret_s8_s32
+// CHECK-LABEL: test_vreinterpret_s8_s32
 int8x8_t test_vreinterpret_s8_s32(int32x2_t a) {
   return vreinterpret_s8_s32(a);
 }
 
-// CHECK: test_vreinterpret_s8_s64
+// CHECK-LABEL: test_vreinterpret_s8_s64
 int8x8_t test_vreinterpret_s8_s64(int64x1_t a) {
   return vreinterpret_s8_s64(a);
 }
 
-// CHECK: test_vreinterpret_s8_u8
+// CHECK-LABEL: test_vreinterpret_s8_u8
 int8x8_t test_vreinterpret_s8_u8(uint8x8_t a) {
   return vreinterpret_s8_u8(a);
 }
 
-// CHECK: test_vreinterpret_s8_u16
+// CHECK-LABEL: test_vreinterpret_s8_u16
 int8x8_t test_vreinterpret_s8_u16(uint16x4_t a) {
   return vreinterpret_s8_u16(a);
 }
 
-// CHECK: test_vreinterpret_s8_u32
+// CHECK-LABEL: test_vreinterpret_s8_u32
 int8x8_t test_vreinterpret_s8_u32(uint32x2_t a) {
   return vreinterpret_s8_u32(a);
 }
 
-// CHECK: test_vreinterpret_s8_u64
+// CHECK-LABEL: test_vreinterpret_s8_u64
 int8x8_t test_vreinterpret_s8_u64(uint64x1_t a) {
   return vreinterpret_s8_u64(a);
 }
 
-// CHECK: test_vreinterpret_s8_f16
+// CHECK-LABEL: test_vreinterpret_s8_f16
 int8x8_t test_vreinterpret_s8_f16(float16x4_t a) {
   return vreinterpret_s8_f16(a);
 }
 
-// CHECK: test_vreinterpret_s8_f32
+// CHECK-LABEL: test_vreinterpret_s8_f32
 int8x8_t test_vreinterpret_s8_f32(float32x2_t a) {
   return vreinterpret_s8_f32(a);
 }
 
-// CHECK: test_vreinterpret_s8_p8
+// CHECK-LABEL: test_vreinterpret_s8_p8
 int8x8_t test_vreinterpret_s8_p8(poly8x8_t a) {
   return vreinterpret_s8_p8(a);
 }
 
-// CHECK: test_vreinterpret_s8_p16
+// CHECK-LABEL: test_vreinterpret_s8_p16
 int8x8_t test_vreinterpret_s8_p16(poly16x4_t a) {
   return vreinterpret_s8_p16(a);
 }
 
-// CHECK: test_vreinterpret_s16_s8
+// CHECK-LABEL: test_vreinterpret_s16_s8
 int16x4_t test_vreinterpret_s16_s8(int8x8_t a) {
   return vreinterpret_s16_s8(a);
 }
 
-// CHECK: test_vreinterpret_s16_s32
+// CHECK-LABEL: test_vreinterpret_s16_s32
 int16x4_t test_vreinterpret_s16_s32(int32x2_t a) {
   return vreinterpret_s16_s32(a);
 }
 
-// CHECK: test_vreinterpret_s16_s64
+// CHECK-LABEL: test_vreinterpret_s16_s64
 int16x4_t test_vreinterpret_s16_s64(int64x1_t a) {
   return vreinterpret_s16_s64(a);
 }
 
-// CHECK: test_vreinterpret_s16_u8
+// CHECK-LABEL: test_vreinterpret_s16_u8
 int16x4_t test_vreinterpret_s16_u8(uint8x8_t a) {
   return vreinterpret_s16_u8(a);
 }
 
-// CHECK: test_vreinterpret_s16_u16
+// CHECK-LABEL: test_vreinterpret_s16_u16
 int16x4_t test_vreinterpret_s16_u16(uint16x4_t a) {
   return vreinterpret_s16_u16(a);
 }
 
-// CHECK: test_vreinterpret_s16_u32
+// CHECK-LABEL: test_vreinterpret_s16_u32
 int16x4_t test_vreinterpret_s16_u32(uint32x2_t a) {
   return vreinterpret_s16_u32(a);
 }
 
-// CHECK: test_vreinterpret_s16_u64
+// CHECK-LABEL: test_vreinterpret_s16_u64
 int16x4_t test_vreinterpret_s16_u64(uint64x1_t a) {
   return vreinterpret_s16_u64(a);
 }
 
-// CHECK: test_vreinterpret_s16_f16
+// CHECK-LABEL: test_vreinterpret_s16_f16
 int16x4_t test_vreinterpret_s16_f16(float16x4_t a) {
   return vreinterpret_s16_f16(a);
 }
 
-// CHECK: test_vreinterpret_s16_f32
+// CHECK-LABEL: test_vreinterpret_s16_f32
 int16x4_t test_vreinterpret_s16_f32(float32x2_t a) {
   return vreinterpret_s16_f32(a);
 }
 
-// CHECK: test_vreinterpret_s16_p8
+// CHECK-LABEL: test_vreinterpret_s16_p8
 int16x4_t test_vreinterpret_s16_p8(poly8x8_t a) {
   return vreinterpret_s16_p8(a);
 }
 
-// CHECK: test_vreinterpret_s16_p16
+// CHECK-LABEL: test_vreinterpret_s16_p16
 int16x4_t test_vreinterpret_s16_p16(poly16x4_t a) {
   return vreinterpret_s16_p16(a);
 }
 
-// CHECK: test_vreinterpret_s32_s8
+// CHECK-LABEL: test_vreinterpret_s32_s8
 int32x2_t test_vreinterpret_s32_s8(int8x8_t a) {
   return vreinterpret_s32_s8(a);
 }
 
-// CHECK: test_vreinterpret_s32_s16
+// CHECK-LABEL: test_vreinterpret_s32_s16
 int32x2_t test_vreinterpret_s32_s16(int16x4_t a) {
   return vreinterpret_s32_s16(a);
 }
 
-// CHECK: test_vreinterpret_s32_s64
+// CHECK-LABEL: test_vreinterpret_s32_s64
 int32x2_t test_vreinterpret_s32_s64(int64x1_t a) {
   return vreinterpret_s32_s64(a);
 }
 
-// CHECK: test_vreinterpret_s32_u8
+// CHECK-LABEL: test_vreinterpret_s32_u8
 int32x2_t test_vreinterpret_s32_u8(uint8x8_t a) {
   return vreinterpret_s32_u8(a);
 }
 
-// CHECK: test_vreinterpret_s32_u16
+// CHECK-LABEL: test_vreinterpret_s32_u16
 int32x2_t test_vreinterpret_s32_u16(uint16x4_t a) {
   return vreinterpret_s32_u16(a);
 }
 
-// CHECK: test_vreinterpret_s32_u32
+// CHECK-LABEL: test_vreinterpret_s32_u32
 int32x2_t test_vreinterpret_s32_u32(uint32x2_t a) {
   return vreinterpret_s32_u32(a);
 }
 
-// CHECK: test_vreinterpret_s32_u64
+// CHECK-LABEL: test_vreinterpret_s32_u64
 int32x2_t test_vreinterpret_s32_u64(uint64x1_t a) {
   return vreinterpret_s32_u64(a);
 }
 
-// CHECK: test_vreinterpret_s32_f16
+// CHECK-LABEL: test_vreinterpret_s32_f16
 int32x2_t test_vreinterpret_s32_f16(float16x4_t a) {
   return vreinterpret_s32_f16(a);
 }
 
-// CHECK: test_vreinterpret_s32_f32
+// CHECK-LABEL: test_vreinterpret_s32_f32
 int32x2_t test_vreinterpret_s32_f32(float32x2_t a) {
   return vreinterpret_s32_f32(a);
 }
 
-// CHECK: test_vreinterpret_s32_p8
+// CHECK-LABEL: test_vreinterpret_s32_p8
 int32x2_t test_vreinterpret_s32_p8(poly8x8_t a) {
   return vreinterpret_s32_p8(a);
 }
 
-// CHECK: test_vreinterpret_s32_p16
+// CHECK-LABEL: test_vreinterpret_s32_p16
 int32x2_t test_vreinterpret_s32_p16(poly16x4_t a) {
   return vreinterpret_s32_p16(a);
 }
 
-// CHECK: test_vreinterpret_s64_s8
+// CHECK-LABEL: test_vreinterpret_s64_s8
 int64x1_t test_vreinterpret_s64_s8(int8x8_t a) {
   return vreinterpret_s64_s8(a);
 }
 
-// CHECK: test_vreinterpret_s64_s16
+// CHECK-LABEL: test_vreinterpret_s64_s16
 int64x1_t test_vreinterpret_s64_s16(int16x4_t a) {
   return vreinterpret_s64_s16(a);
 }
 
-// CHECK: test_vreinterpret_s64_s32
+// CHECK-LABEL: test_vreinterpret_s64_s32
 int64x1_t test_vreinterpret_s64_s32(int32x2_t a) {
   return vreinterpret_s64_s32(a);
 }
 
-// CHECK: test_vreinterpret_s64_u8
+// CHECK-LABEL: test_vreinterpret_s64_u8
 int64x1_t test_vreinterpret_s64_u8(uint8x8_t a) {
   return vreinterpret_s64_u8(a);
 }
 
-// CHECK: test_vreinterpret_s64_u16
+// CHECK-LABEL: test_vreinterpret_s64_u16
 int64x1_t test_vreinterpret_s64_u16(uint16x4_t a) {
   return vreinterpret_s64_u16(a);
 }
 
-// CHECK: test_vreinterpret_s64_u32
+// CHECK-LABEL: test_vreinterpret_s64_u32
 int64x1_t test_vreinterpret_s64_u32(uint32x2_t a) {
   return vreinterpret_s64_u32(a);
 }
 
-// CHECK: test_vreinterpret_s64_u64
+// CHECK-LABEL: test_vreinterpret_s64_u64
 int64x1_t test_vreinterpret_s64_u64(uint64x1_t a) {
   return vreinterpret_s64_u64(a);
 }
 
-// CHECK: test_vreinterpret_s64_f16
+// CHECK-LABEL: test_vreinterpret_s64_f16
 int64x1_t test_vreinterpret_s64_f16(float16x4_t a) {
   return vreinterpret_s64_f16(a);
 }
 
-// CHECK: test_vreinterpret_s64_f32
+// CHECK-LABEL: test_vreinterpret_s64_f32
 int64x1_t test_vreinterpret_s64_f32(float32x2_t a) {
   return vreinterpret_s64_f32(a);
 }
 
-// CHECK: test_vreinterpret_s64_p8
+// CHECK-LABEL: test_vreinterpret_s64_p8
 int64x1_t test_vreinterpret_s64_p8(poly8x8_t a) {
   return vreinterpret_s64_p8(a);
 }
 
-// CHECK: test_vreinterpret_s64_p16
+// CHECK-LABEL: test_vreinterpret_s64_p16
 int64x1_t test_vreinterpret_s64_p16(poly16x4_t a) {
   return vreinterpret_s64_p16(a);
 }
 
-// CHECK: test_vreinterpret_u8_s8
+// CHECK-LABEL: test_vreinterpret_u8_s8
 uint8x8_t test_vreinterpret_u8_s8(int8x8_t a) {
   return vreinterpret_u8_s8(a);
 }
 
-// CHECK: test_vreinterpret_u8_s16
+// CHECK-LABEL: test_vreinterpret_u8_s16
 uint8x8_t test_vreinterpret_u8_s16(int16x4_t a) {
   return vreinterpret_u8_s16(a);
 }
 
-// CHECK: test_vreinterpret_u8_s32
+// CHECK-LABEL: test_vreinterpret_u8_s32
 uint8x8_t test_vreinterpret_u8_s32(int32x2_t a) {
   return vreinterpret_u8_s32(a);
 }
 
-// CHECK: test_vreinterpret_u8_s64
+// CHECK-LABEL: test_vreinterpret_u8_s64
 uint8x8_t test_vreinterpret_u8_s64(int64x1_t a) {
   return vreinterpret_u8_s64(a);
 }
 
-// CHECK: test_vreinterpret_u8_u16
+// CHECK-LABEL: test_vreinterpret_u8_u16
 uint8x8_t test_vreinterpret_u8_u16(uint16x4_t a) {
   return vreinterpret_u8_u16(a);
 }
 
-// CHECK: test_vreinterpret_u8_u32
+// CHECK-LABEL: test_vreinterpret_u8_u32
 uint8x8_t test_vreinterpret_u8_u32(uint32x2_t a) {
   return vreinterpret_u8_u32(a);
 }
 
-// CHECK: test_vreinterpret_u8_u64
+// CHECK-LABEL: test_vreinterpret_u8_u64
 uint8x8_t test_vreinterpret_u8_u64(uint64x1_t a) {
   return vreinterpret_u8_u64(a);
 }
 
-// CHECK: test_vreinterpret_u8_f16
+// CHECK-LABEL: test_vreinterpret_u8_f16
 uint8x8_t test_vreinterpret_u8_f16(float16x4_t a) {
   return vreinterpret_u8_f16(a);
 }
 
-// CHECK: test_vreinterpret_u8_f32
+// CHECK-LABEL: test_vreinterpret_u8_f32
 uint8x8_t test_vreinterpret_u8_f32(float32x2_t a) {
   return vreinterpret_u8_f32(a);
 }
 
-// CHECK: test_vreinterpret_u8_p8
+// CHECK-LABEL: test_vreinterpret_u8_p8
 uint8x8_t test_vreinterpret_u8_p8(poly8x8_t a) {
   return vreinterpret_u8_p8(a);
 }
 
-// CHECK: test_vreinterpret_u8_p16
+// CHECK-LABEL: test_vreinterpret_u8_p16
 uint8x8_t test_vreinterpret_u8_p16(poly16x4_t a) {
   return vreinterpret_u8_p16(a);
 }
 
-// CHECK: test_vreinterpret_u16_s8
+// CHECK-LABEL: test_vreinterpret_u16_s8
 uint16x4_t test_vreinterpret_u16_s8(int8x8_t a) {
   return vreinterpret_u16_s8(a);
 }
 
-// CHECK: test_vreinterpret_u16_s16
+// CHECK-LABEL: test_vreinterpret_u16_s16
 uint16x4_t test_vreinterpret_u16_s16(int16x4_t a) {
   return vreinterpret_u16_s16(a);
 }
 
-// CHECK: test_vreinterpret_u16_s32
+// CHECK-LABEL: test_vreinterpret_u16_s32
 uint16x4_t test_vreinterpret_u16_s32(int32x2_t a) {
   return vreinterpret_u16_s32(a);
 }
 
-// CHECK: test_vreinterpret_u16_s64
+// CHECK-LABEL: test_vreinterpret_u16_s64
 uint16x4_t test_vreinterpret_u16_s64(int64x1_t a) {
   return vreinterpret_u16_s64(a);
 }
 
-// CHECK: test_vreinterpret_u16_u8
+// CHECK-LABEL: test_vreinterpret_u16_u8
 uint16x4_t test_vreinterpret_u16_u8(uint8x8_t a) {
   return vreinterpret_u16_u8(a);
 }
 
-// CHECK: test_vreinterpret_u16_u32
+// CHECK-LABEL: test_vreinterpret_u16_u32
 uint16x4_t test_vreinterpret_u16_u32(uint32x2_t a) {
   return vreinterpret_u16_u32(a);
 }
 
-// CHECK: test_vreinterpret_u16_u64
+// CHECK-LABEL: test_vreinterpret_u16_u64
 uint16x4_t test_vreinterpret_u16_u64(uint64x1_t a) {
   return vreinterpret_u16_u64(a);
 }
 
-// CHECK: test_vreinterpret_u16_f16
+// CHECK-LABEL: test_vreinterpret_u16_f16
 uint16x4_t test_vreinterpret_u16_f16(float16x4_t a) {
   return vreinterpret_u16_f16(a);
 }
 
-// CHECK: test_vreinterpret_u16_f32
+// CHECK-LABEL: test_vreinterpret_u16_f32
 uint16x4_t test_vreinterpret_u16_f32(float32x2_t a) {
   return vreinterpret_u16_f32(a);
 }
 
-// CHECK: test_vreinterpret_u16_p8
+// CHECK-LABEL: test_vreinterpret_u16_p8
 uint16x4_t test_vreinterpret_u16_p8(poly8x8_t a) {
   return vreinterpret_u16_p8(a);
 }
 
-// CHECK: test_vreinterpret_u16_p16
+// CHECK-LABEL: test_vreinterpret_u16_p16
 uint16x4_t test_vreinterpret_u16_p16(poly16x4_t a) {
   return vreinterpret_u16_p16(a);
 }
 
-// CHECK: test_vreinterpret_u32_s8
+// CHECK-LABEL: test_vreinterpret_u32_s8
 uint32x2_t test_vreinterpret_u32_s8(int8x8_t a) {
   return vreinterpret_u32_s8(a);
 }
 
-// CHECK: test_vreinterpret_u32_s16
+// CHECK-LABEL: test_vreinterpret_u32_s16
 uint32x2_t test_vreinterpret_u32_s16(int16x4_t a) {
   return vreinterpret_u32_s16(a);
 }
 
-// CHECK: test_vreinterpret_u32_s32
+// CHECK-LABEL: test_vreinterpret_u32_s32
 uint32x2_t test_vreinterpret_u32_s32(int32x2_t a) {
   return vreinterpret_u32_s32(a);
 }
 
-// CHECK: test_vreinterpret_u32_s64
+// CHECK-LABEL: test_vreinterpret_u32_s64
 uint32x2_t test_vreinterpret_u32_s64(int64x1_t a) {
   return vreinterpret_u32_s64(a);
 }
 
-// CHECK: test_vreinterpret_u32_u8
+// CHECK-LABEL: test_vreinterpret_u32_u8
 uint32x2_t test_vreinterpret_u32_u8(uint8x8_t a) {
   return vreinterpret_u32_u8(a);
 }
 
-// CHECK: test_vreinterpret_u32_u16
+// CHECK-LABEL: test_vreinterpret_u32_u16
 uint32x2_t test_vreinterpret_u32_u16(uint16x4_t a) {
   return vreinterpret_u32_u16(a);
 }
 
-// CHECK: test_vreinterpret_u32_u64
+// CHECK-LABEL: test_vreinterpret_u32_u64
 uint32x2_t test_vreinterpret_u32_u64(uint64x1_t a) {
   return vreinterpret_u32_u64(a);
 }
 
-// CHECK: test_vreinterpret_u32_f16
+// CHECK-LABEL: test_vreinterpret_u32_f16
 uint32x2_t test_vreinterpret_u32_f16(float16x4_t a) {
   return vreinterpret_u32_f16(a);
 }
 
-// CHECK: test_vreinterpret_u32_f32
+// CHECK-LABEL: test_vreinterpret_u32_f32
 uint32x2_t test_vreinterpret_u32_f32(float32x2_t a) {
   return vreinterpret_u32_f32(a);
 }
 
-// CHECK: test_vreinterpret_u32_p8
+// CHECK-LABEL: test_vreinterpret_u32_p8
 uint32x2_t test_vreinterpret_u32_p8(poly8x8_t a) {
   return vreinterpret_u32_p8(a);
 }
 
-// CHECK: test_vreinterpret_u32_p16
+// CHECK-LABEL: test_vreinterpret_u32_p16
 uint32x2_t test_vreinterpret_u32_p16(poly16x4_t a) {
   return vreinterpret_u32_p16(a);
 }
 
-// CHECK: test_vreinterpret_u64_s8
+// CHECK-LABEL: test_vreinterpret_u64_s8
 uint64x1_t test_vreinterpret_u64_s8(int8x8_t a) {
   return vreinterpret_u64_s8(a);
 }
 
-// CHECK: test_vreinterpret_u64_s16
+// CHECK-LABEL: test_vreinterpret_u64_s16
 uint64x1_t test_vreinterpret_u64_s16(int16x4_t a) {
   return vreinterpret_u64_s16(a);
 }
 
-// CHECK: test_vreinterpret_u64_s32
+// CHECK-LABEL: test_vreinterpret_u64_s32
 uint64x1_t test_vreinterpret_u64_s32(int32x2_t a) {
   return vreinterpret_u64_s32(a);
 }
 
-// CHECK: test_vreinterpret_u64_s64
+// CHECK-LABEL: test_vreinterpret_u64_s64
 uint64x1_t test_vreinterpret_u64_s64(int64x1_t a) {
   return vreinterpret_u64_s64(a);
 }
 
-// CHECK: test_vreinterpret_u64_u8
+// CHECK-LABEL: test_vreinterpret_u64_u8
 uint64x1_t test_vreinterpret_u64_u8(uint8x8_t a) {
   return vreinterpret_u64_u8(a);
 }
 
-// CHECK: test_vreinterpret_u64_u16
+// CHECK-LABEL: test_vreinterpret_u64_u16
 uint64x1_t test_vreinterpret_u64_u16(uint16x4_t a) {
   return vreinterpret_u64_u16(a);
 }
 
-// CHECK: test_vreinterpret_u64_u32
+// CHECK-LABEL: test_vreinterpret_u64_u32
 uint64x1_t test_vreinterpret_u64_u32(uint32x2_t a) {
   return vreinterpret_u64_u32(a);
 }
 
-// CHECK: test_vreinterpret_u64_f16
+// CHECK-LABEL: test_vreinterpret_u64_f16
 uint64x1_t test_vreinterpret_u64_f16(float16x4_t a) {
   return vreinterpret_u64_f16(a);
 }
 
-// CHECK: test_vreinterpret_u64_f32
+// CHECK-LABEL: test_vreinterpret_u64_f32
 uint64x1_t test_vreinterpret_u64_f32(float32x2_t a) {
   return vreinterpret_u64_f32(a);
 }
 
-// CHECK: test_vreinterpret_u64_p8
+// CHECK-LABEL: test_vreinterpret_u64_p8
 uint64x1_t test_vreinterpret_u64_p8(poly8x8_t a) {
   return vreinterpret_u64_p8(a);
 }
 
-// CHECK: test_vreinterpret_u64_p16
+// CHECK-LABEL: test_vreinterpret_u64_p16
 uint64x1_t test_vreinterpret_u64_p16(poly16x4_t a) {
   return vreinterpret_u64_p16(a);
 }
 
-// CHECK: test_vreinterpret_f16_s8
+// CHECK-LABEL: test_vreinterpret_f16_s8
 float16x4_t test_vreinterpret_f16_s8(int8x8_t a) {
   return vreinterpret_f16_s8(a);
 }
 
-// CHECK: test_vreinterpret_f16_s16
+// CHECK-LABEL: test_vreinterpret_f16_s16
 float16x4_t test_vreinterpret_f16_s16(int16x4_t a) {
   return vreinterpret_f16_s16(a);
 }
 
-// CHECK: test_vreinterpret_f16_s32
+// CHECK-LABEL: test_vreinterpret_f16_s32
 float16x4_t test_vreinterpret_f16_s32(int32x2_t a) {
   return vreinterpret_f16_s32(a);
 }
 
-// CHECK: test_vreinterpret_f16_s64
+// CHECK-LABEL: test_vreinterpret_f16_s64
 float16x4_t test_vreinterpret_f16_s64(int64x1_t a) {
   return vreinterpret_f16_s64(a);
 }
 
-// CHECK: test_vreinterpret_f16_u8
+// CHECK-LABEL: test_vreinterpret_f16_u8
 float16x4_t test_vreinterpret_f16_u8(uint8x8_t a) {
   return vreinterpret_f16_u8(a);
 }
 
-// CHECK: test_vreinterpret_f16_u16
+// CHECK-LABEL: test_vreinterpret_f16_u16
 float16x4_t test_vreinterpret_f16_u16(uint16x4_t a) {
   return vreinterpret_f16_u16(a);
 }
 
-// CHECK: test_vreinterpret_f16_u32
+// CHECK-LABEL: test_vreinterpret_f16_u32
 float16x4_t test_vreinterpret_f16_u32(uint32x2_t a) {
   return vreinterpret_f16_u32(a);
 }
 
-// CHECK: test_vreinterpret_f16_u64
+// CHECK-LABEL: test_vreinterpret_f16_u64
 float16x4_t test_vreinterpret_f16_u64(uint64x1_t a) {
   return vreinterpret_f16_u64(a);
 }
 
-// CHECK: test_vreinterpret_f16_f32
+// CHECK-LABEL: test_vreinterpret_f16_f32
 float16x4_t test_vreinterpret_f16_f32(float32x2_t a) {
   return vreinterpret_f16_f32(a);
 }
 
-// CHECK: test_vreinterpret_f16_p8
+// CHECK-LABEL: test_vreinterpret_f16_p8
 float16x4_t test_vreinterpret_f16_p8(poly8x8_t a) {
   return vreinterpret_f16_p8(a);
 }
 
-// CHECK: test_vreinterpret_f16_p16
+// CHECK-LABEL: test_vreinterpret_f16_p16
 float16x4_t test_vreinterpret_f16_p16(poly16x4_t a) {
   return vreinterpret_f16_p16(a);
 }
 
-// CHECK: test_vreinterpret_f32_s8
+// CHECK-LABEL: test_vreinterpret_f32_s8
 float32x2_t test_vreinterpret_f32_s8(int8x8_t a) {
   return vreinterpret_f32_s8(a);
 }
 
-// CHECK: test_vreinterpret_f32_s16
+// CHECK-LABEL: test_vreinterpret_f32_s16
 float32x2_t test_vreinterpret_f32_s16(int16x4_t a) {
   return vreinterpret_f32_s16(a);
 }
 
-// CHECK: test_vreinterpret_f32_s32
+// CHECK-LABEL: test_vreinterpret_f32_s32
 float32x2_t test_vreinterpret_f32_s32(int32x2_t a) {
   return vreinterpret_f32_s32(a);
 }
 
-// CHECK: test_vreinterpret_f32_s64
+// CHECK-LABEL: test_vreinterpret_f32_s64
 float32x2_t test_vreinterpret_f32_s64(int64x1_t a) {
   return vreinterpret_f32_s64(a);
 }
 
-// CHECK: test_vreinterpret_f32_u8
+// CHECK-LABEL: test_vreinterpret_f32_u8
 float32x2_t test_vreinterpret_f32_u8(uint8x8_t a) {
   return vreinterpret_f32_u8(a);
 }
 
-// CHECK: test_vreinterpret_f32_u16
+// CHECK-LABEL: test_vreinterpret_f32_u16
 float32x2_t test_vreinterpret_f32_u16(uint16x4_t a) {
   return vreinterpret_f32_u16(a);
 }
 
-// CHECK: test_vreinterpret_f32_u32
+// CHECK-LABEL: test_vreinterpret_f32_u32
 float32x2_t test_vreinterpret_f32_u32(uint32x2_t a) {
   return vreinterpret_f32_u32(a);
 }
 
-// CHECK: test_vreinterpret_f32_u64
+// CHECK-LABEL: test_vreinterpret_f32_u64
 float32x2_t test_vreinterpret_f32_u64(uint64x1_t a) {
   return vreinterpret_f32_u64(a);
 }
 
-// CHECK: test_vreinterpret_f32_f16
+// CHECK-LABEL: test_vreinterpret_f32_f16
 float32x2_t test_vreinterpret_f32_f16(float16x4_t a) {
   return vreinterpret_f32_f16(a);
 }
 
-// CHECK: test_vreinterpret_f32_p8
+// CHECK-LABEL: test_vreinterpret_f32_p8
 float32x2_t test_vreinterpret_f32_p8(poly8x8_t a) {
   return vreinterpret_f32_p8(a);
 }
 
-// CHECK: test_vreinterpret_f32_p16
+// CHECK-LABEL: test_vreinterpret_f32_p16
 float32x2_t test_vreinterpret_f32_p16(poly16x4_t a) {
   return vreinterpret_f32_p16(a);
 }
 
-// CHECK: test_vreinterpret_p8_s8
+// CHECK-LABEL: test_vreinterpret_p8_s8
 poly8x8_t test_vreinterpret_p8_s8(int8x8_t a) {
   return vreinterpret_p8_s8(a);
 }
 
-// CHECK: test_vreinterpret_p8_s16
+// CHECK-LABEL: test_vreinterpret_p8_s16
 poly8x8_t test_vreinterpret_p8_s16(int16x4_t a) {
   return vreinterpret_p8_s16(a);
 }
 
-// CHECK: test_vreinterpret_p8_s32
+// CHECK-LABEL: test_vreinterpret_p8_s32
 poly8x8_t test_vreinterpret_p8_s32(int32x2_t a) {
   return vreinterpret_p8_s32(a);
 }
 
-// CHECK: test_vreinterpret_p8_s64
+// CHECK-LABEL: test_vreinterpret_p8_s64
 poly8x8_t test_vreinterpret_p8_s64(int64x1_t a) {
   return vreinterpret_p8_s64(a);
 }
 
-// CHECK: test_vreinterpret_p8_u8
+// CHECK-LABEL: test_vreinterpret_p8_u8
 poly8x8_t test_vreinterpret_p8_u8(uint8x8_t a) {
   return vreinterpret_p8_u8(a);
 }
 
-// CHECK: test_vreinterpret_p8_u16
+// CHECK-LABEL: test_vreinterpret_p8_u16
 poly8x8_t test_vreinterpret_p8_u16(uint16x4_t a) {
   return vreinterpret_p8_u16(a);
 }
 
-// CHECK: test_vreinterpret_p8_u32
+// CHECK-LABEL: test_vreinterpret_p8_u32
 poly8x8_t test_vreinterpret_p8_u32(uint32x2_t a) {
   return vreinterpret_p8_u32(a);
 }
 
-// CHECK: test_vreinterpret_p8_u64
+// CHECK-LABEL: test_vreinterpret_p8_u64
 poly8x8_t test_vreinterpret_p8_u64(uint64x1_t a) {
   return vreinterpret_p8_u64(a);
 }
 
-// CHECK: test_vreinterpret_p8_f16
+// CHECK-LABEL: test_vreinterpret_p8_f16
 poly8x8_t test_vreinterpret_p8_f16(float16x4_t a) {
   return vreinterpret_p8_f16(a);
 }
 
-// CHECK: test_vreinterpret_p8_f32
+// CHECK-LABEL: test_vreinterpret_p8_f32
 poly8x8_t test_vreinterpret_p8_f32(float32x2_t a) {
   return vreinterpret_p8_f32(a);
 }
 
-// CHECK: test_vreinterpret_p8_p16
+// CHECK-LABEL: test_vreinterpret_p8_p16
 poly8x8_t test_vreinterpret_p8_p16(poly16x4_t a) {
   return vreinterpret_p8_p16(a);
 }
 
-// CHECK: test_vreinterpret_p16_s8
+// CHECK-LABEL: test_vreinterpret_p16_s8
 poly16x4_t test_vreinterpret_p16_s8(int8x8_t a) {
   return vreinterpret_p16_s8(a);
 }
 
-// CHECK: test_vreinterpret_p16_s16
+// CHECK-LABEL: test_vreinterpret_p16_s16
 poly16x4_t test_vreinterpret_p16_s16(int16x4_t a) {
   return vreinterpret_p16_s16(a);
 }
 
-// CHECK: test_vreinterpret_p16_s32
+// CHECK-LABEL: test_vreinterpret_p16_s32
 poly16x4_t test_vreinterpret_p16_s32(int32x2_t a) {
   return vreinterpret_p16_s32(a);
 }
 
-// CHECK: test_vreinterpret_p16_s64
+// CHECK-LABEL: test_vreinterpret_p16_s64
 poly16x4_t test_vreinterpret_p16_s64(int64x1_t a) {
   return vreinterpret_p16_s64(a);
 }
 
-// CHECK: test_vreinterpret_p16_u8
+// CHECK-LABEL: test_vreinterpret_p16_u8
 poly16x4_t test_vreinterpret_p16_u8(uint8x8_t a) {
   return vreinterpret_p16_u8(a);
 }
 
-// CHECK: test_vreinterpret_p16_u16
+// CHECK-LABEL: test_vreinterpret_p16_u16
 poly16x4_t test_vreinterpret_p16_u16(uint16x4_t a) {
   return vreinterpret_p16_u16(a);
 }
 
-// CHECK: test_vreinterpret_p16_u32
+// CHECK-LABEL: test_vreinterpret_p16_u32
 poly16x4_t test_vreinterpret_p16_u32(uint32x2_t a) {
   return vreinterpret_p16_u32(a);
 }
 
-// CHECK: test_vreinterpret_p16_u64
+// CHECK-LABEL: test_vreinterpret_p16_u64
 poly16x4_t test_vreinterpret_p16_u64(uint64x1_t a) {
   return vreinterpret_p16_u64(a);
 }
 
-// CHECK: test_vreinterpret_p16_f16
+// CHECK-LABEL: test_vreinterpret_p16_f16
 poly16x4_t test_vreinterpret_p16_f16(float16x4_t a) {
   return vreinterpret_p16_f16(a);
 }
 
-// CHECK: test_vreinterpret_p16_f32
+// CHECK-LABEL: test_vreinterpret_p16_f32
 poly16x4_t test_vreinterpret_p16_f32(float32x2_t a) {
   return vreinterpret_p16_f32(a);
 }
 
-// CHECK: test_vreinterpret_p16_p8
+// CHECK-LABEL: test_vreinterpret_p16_p8
 poly16x4_t test_vreinterpret_p16_p8(poly8x8_t a) {
   return vreinterpret_p16_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s8_s16
+// CHECK-LABEL: test_vreinterpretq_s8_s16
 int8x16_t test_vreinterpretq_s8_s16(int16x8_t a) {
   return vreinterpretq_s8_s16(a);
 }
 
-// CHECK: test_vreinterpretq_s8_s32
+// CHECK-LABEL: test_vreinterpretq_s8_s32
 int8x16_t test_vreinterpretq_s8_s32(int32x4_t a) {
   return vreinterpretq_s8_s32(a);
 }
 
-// CHECK: test_vreinterpretq_s8_s64
+// CHECK-LABEL: test_vreinterpretq_s8_s64
 int8x16_t test_vreinterpretq_s8_s64(int64x2_t a) {
   return vreinterpretq_s8_s64(a);
 }
 
-// CHECK: test_vreinterpretq_s8_u8
+// CHECK-LABEL: test_vreinterpretq_s8_u8
 int8x16_t test_vreinterpretq_s8_u8(uint8x16_t a) {
   return vreinterpretq_s8_u8(a);
 }
 
-// CHECK: test_vreinterpretq_s8_u16
+// CHECK-LABEL: test_vreinterpretq_s8_u16
 int8x16_t test_vreinterpretq_s8_u16(uint16x8_t a) {
   return vreinterpretq_s8_u16(a);
 }
 
-// CHECK: test_vreinterpretq_s8_u32
+// CHECK-LABEL: test_vreinterpretq_s8_u32
 int8x16_t test_vreinterpretq_s8_u32(uint32x4_t a) {
   return vreinterpretq_s8_u32(a);
 }
 
-// CHECK: test_vreinterpretq_s8_u64
+// CHECK-LABEL: test_vreinterpretq_s8_u64
 int8x16_t test_vreinterpretq_s8_u64(uint64x2_t a) {
   return vreinterpretq_s8_u64(a);
 }
 
-// CHECK: test_vreinterpretq_s8_f16
+// CHECK-LABEL: test_vreinterpretq_s8_f16
 int8x16_t test_vreinterpretq_s8_f16(float16x8_t a) {
   return vreinterpretq_s8_f16(a);
 }
 
-// CHECK: test_vreinterpretq_s8_f32
+// CHECK-LABEL: test_vreinterpretq_s8_f32
 int8x16_t test_vreinterpretq_s8_f32(float32x4_t a) {
   return vreinterpretq_s8_f32(a);
 }
 
-// CHECK: test_vreinterpretq_s8_p8
+// CHECK-LABEL: test_vreinterpretq_s8_p8
 int8x16_t test_vreinterpretq_s8_p8(poly8x16_t a) {
   return vreinterpretq_s8_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s8_p16
+// CHECK-LABEL: test_vreinterpretq_s8_p16
 int8x16_t test_vreinterpretq_s8_p16(poly16x8_t a) {
   return vreinterpretq_s8_p16(a);
 }
 
-// CHECK: test_vreinterpretq_s16_s8
+// CHECK-LABEL: test_vreinterpretq_s16_s8
 int16x8_t test_vreinterpretq_s16_s8(int8x16_t a) {
   return vreinterpretq_s16_s8(a);
 }
 
-// CHECK: test_vreinterpretq_s16_s32
+// CHECK-LABEL: test_vreinterpretq_s16_s32
 int16x8_t test_vreinterpretq_s16_s32(int32x4_t a) {
   return vreinterpretq_s16_s32(a);
 }
 
-// CHECK: test_vreinterpretq_s16_s64
+// CHECK-LABEL: test_vreinterpretq_s16_s64
 int16x8_t test_vreinterpretq_s16_s64(int64x2_t a) {
   return vreinterpretq_s16_s64(a);
 }
 
-// CHECK: test_vreinterpretq_s16_u8
+// CHECK-LABEL: test_vreinterpretq_s16_u8
 int16x8_t test_vreinterpretq_s16_u8(uint8x16_t a) {
   return vreinterpretq_s16_u8(a);
 }
 
-// CHECK: test_vreinterpretq_s16_u16
+// CHECK-LABEL: test_vreinterpretq_s16_u16
 int16x8_t test_vreinterpretq_s16_u16(uint16x8_t a) {
   return vreinterpretq_s16_u16(a);
 }
 
-// CHECK: test_vreinterpretq_s16_u32
+// CHECK-LABEL: test_vreinterpretq_s16_u32
 int16x8_t test_vreinterpretq_s16_u32(uint32x4_t a) {
   return vreinterpretq_s16_u32(a);
 }
 
-// CHECK: test_vreinterpretq_s16_u64
+// CHECK-LABEL: test_vreinterpretq_s16_u64
 int16x8_t test_vreinterpretq_s16_u64(uint64x2_t a) {
   return vreinterpretq_s16_u64(a);
 }
 
-// CHECK: test_vreinterpretq_s16_f16
+// CHECK-LABEL: test_vreinterpretq_s16_f16
 int16x8_t test_vreinterpretq_s16_f16(float16x8_t a) {
   return vreinterpretq_s16_f16(a);
 }
 
-// CHECK: test_vreinterpretq_s16_f32
+// CHECK-LABEL: test_vreinterpretq_s16_f32
 int16x8_t test_vreinterpretq_s16_f32(float32x4_t a) {
   return vreinterpretq_s16_f32(a);
 }
 
-// CHECK: test_vreinterpretq_s16_p8
+// CHECK-LABEL: test_vreinterpretq_s16_p8
 int16x8_t test_vreinterpretq_s16_p8(poly8x16_t a) {
   return vreinterpretq_s16_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s16_p16
+// CHECK-LABEL: test_vreinterpretq_s16_p16
 int16x8_t test_vreinterpretq_s16_p16(poly16x8_t a) {
   return vreinterpretq_s16_p16(a);
 }
 
-// CHECK: test_vreinterpretq_s32_s8
+// CHECK-LABEL: test_vreinterpretq_s32_s8
 int32x4_t test_vreinterpretq_s32_s8(int8x16_t a) {
   return vreinterpretq_s32_s8(a);
 }
 
-// CHECK: test_vreinterpretq_s32_s16
+// CHECK-LABEL: test_vreinterpretq_s32_s16
 int32x4_t test_vreinterpretq_s32_s16(int16x8_t a) {
   return vreinterpretq_s32_s16(a);
 }
 
-// CHECK: test_vreinterpretq_s32_s64
+// CHECK-LABEL: test_vreinterpretq_s32_s64
 int32x4_t test_vreinterpretq_s32_s64(int64x2_t a) {
   return vreinterpretq_s32_s64(a);
 }
 
-// CHECK: test_vreinterpretq_s32_u8
+// CHECK-LABEL: test_vreinterpretq_s32_u8
 int32x4_t test_vreinterpretq_s32_u8(uint8x16_t a) {
   return vreinterpretq_s32_u8(a);
 }
 
-// CHECK: test_vreinterpretq_s32_u16
+// CHECK-LABEL: test_vreinterpretq_s32_u16
 int32x4_t test_vreinterpretq_s32_u16(uint16x8_t a) {
   return vreinterpretq_s32_u16(a);
 }
 
-// CHECK: test_vreinterpretq_s32_u32
+// CHECK-LABEL: test_vreinterpretq_s32_u32
 int32x4_t test_vreinterpretq_s32_u32(uint32x4_t a) {
   return vreinterpretq_s32_u32(a);
 }
 
-// CHECK: test_vreinterpretq_s32_u64
+// CHECK-LABEL: test_vreinterpretq_s32_u64
 int32x4_t test_vreinterpretq_s32_u64(uint64x2_t a) {
   return vreinterpretq_s32_u64(a);
 }
 
-// CHECK: test_vreinterpretq_s32_f16
+// CHECK-LABEL: test_vreinterpretq_s32_f16
 int32x4_t test_vreinterpretq_s32_f16(float16x8_t a) {
   return vreinterpretq_s32_f16(a);
 }
 
-// CHECK: test_vreinterpretq_s32_f32
+// CHECK-LABEL: test_vreinterpretq_s32_f32
 int32x4_t test_vreinterpretq_s32_f32(float32x4_t a) {
   return vreinterpretq_s32_f32(a);
 }
 
-// CHECK: test_vreinterpretq_s32_p8
+// CHECK-LABEL: test_vreinterpretq_s32_p8
 int32x4_t test_vreinterpretq_s32_p8(poly8x16_t a) {
   return vreinterpretq_s32_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s32_p16
+// CHECK-LABEL: test_vreinterpretq_s32_p16
 int32x4_t test_vreinterpretq_s32_p16(poly16x8_t a) {
   return vreinterpretq_s32_p16(a);
 }
 
-// CHECK: test_vreinterpretq_s64_s8
+// CHECK-LABEL: test_vreinterpretq_s64_s8
 int64x2_t test_vreinterpretq_s64_s8(int8x16_t a) {
   return vreinterpretq_s64_s8(a);
 }
 
-// CHECK: test_vreinterpretq_s64_s16
+// CHECK-LABEL: test_vreinterpretq_s64_s16
 int64x2_t test_vreinterpretq_s64_s16(int16x8_t a) {
   return vreinterpretq_s64_s16(a);
 }
 
-// CHECK: test_vreinterpretq_s64_s32
+// CHECK-LABEL: test_vreinterpretq_s64_s32
 int64x2_t test_vreinterpretq_s64_s32(int32x4_t a) {
   return vreinterpretq_s64_s32(a);
 }
 
-// CHECK: test_vreinterpretq_s64_u8
+// CHECK-LABEL: test_vreinterpretq_s64_u8
 int64x2_t test_vreinterpretq_s64_u8(uint8x16_t a) {
   return vreinterpretq_s64_u8(a);
 }
 
-// CHECK: test_vreinterpretq_s64_u16
+// CHECK-LABEL: test_vreinterpretq_s64_u16
 int64x2_t test_vreinterpretq_s64_u16(uint16x8_t a) {
   return vreinterpretq_s64_u16(a);
 }
 
-// CHECK: test_vreinterpretq_s64_u32
+// CHECK-LABEL: test_vreinterpretq_s64_u32
 int64x2_t test_vreinterpretq_s64_u32(uint32x4_t a) {
   return vreinterpretq_s64_u32(a);
 }
 
-// CHECK: test_vreinterpretq_s64_u64
+// CHECK-LABEL: test_vreinterpretq_s64_u64
 int64x2_t test_vreinterpretq_s64_u64(uint64x2_t a) {
   return vreinterpretq_s64_u64(a);
 }
 
-// CHECK: test_vreinterpretq_s64_f16
+// CHECK-LABEL: test_vreinterpretq_s64_f16
 int64x2_t test_vreinterpretq_s64_f16(float16x8_t a) {
   return vreinterpretq_s64_f16(a);
 }
 
-// CHECK: test_vreinterpretq_s64_f32
+// CHECK-LABEL: test_vreinterpretq_s64_f32
 int64x2_t test_vreinterpretq_s64_f32(float32x4_t a) {
   return vreinterpretq_s64_f32(a);
 }
 
-// CHECK: test_vreinterpretq_s64_p8
+// CHECK-LABEL: test_vreinterpretq_s64_p8
 int64x2_t test_vreinterpretq_s64_p8(poly8x16_t a) {
   return vreinterpretq_s64_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s64_p16
+// CHECK-LABEL: test_vreinterpretq_s64_p16
 int64x2_t test_vreinterpretq_s64_p16(poly16x8_t a) {
   return vreinterpretq_s64_p16(a);
 }
 
-// CHECK: test_vreinterpretq_u8_s8
+// CHECK-LABEL: test_vreinterpretq_u8_s8
 uint8x16_t test_vreinterpretq_u8_s8(int8x16_t a) {
   return vreinterpretq_u8_s8(a);
 }
 
-// CHECK: test_vreinterpretq_u8_s16
+// CHECK-LABEL: test_vreinterpretq_u8_s16
 uint8x16_t test_vreinterpretq_u8_s16(int16x8_t a) {
   return vreinterpretq_u8_s16(a);
 }
 
-// CHECK: test_vreinterpretq_u8_s32
+// CHECK-LABEL: test_vreinterpretq_u8_s32
 uint8x16_t test_vreinterpretq_u8_s32(int32x4_t a) {
   return vreinterpretq_u8_s32(a);
 }
 
-// CHECK: test_vreinterpretq_u8_s64
+// CHECK-LABEL: test_vreinterpretq_u8_s64
 uint8x16_t test_vreinterpretq_u8_s64(int64x2_t a) {
   return vreinterpretq_u8_s64(a);
 }
 
-// CHECK: test_vreinterpretq_u8_u16
+// CHECK-LABEL: test_vreinterpretq_u8_u16
 uint8x16_t test_vreinterpretq_u8_u16(uint16x8_t a) {
   return vreinterpretq_u8_u16(a);
 }
 
-// CHECK: test_vreinterpretq_u8_u32
+// CHECK-LABEL: test_vreinterpretq_u8_u32
 uint8x16_t test_vreinterpretq_u8_u32(uint32x4_t a) {
   return vreinterpretq_u8_u32(a);
 }
 
-// CHECK: test_vreinterpretq_u8_u64
+// CHECK-LABEL: test_vreinterpretq_u8_u64
 uint8x16_t test_vreinterpretq_u8_u64(uint64x2_t a) {
   return vreinterpretq_u8_u64(a);
 }
 
-// CHECK: test_vreinterpretq_u8_f16
+// CHECK-LABEL: test_vreinterpretq_u8_f16
 uint8x16_t test_vreinterpretq_u8_f16(float16x8_t a) {
   return vreinterpretq_u8_f16(a);
 }
 
-// CHECK: test_vreinterpretq_u8_f32
+// CHECK-LABEL: test_vreinterpretq_u8_f32
 uint8x16_t test_vreinterpretq_u8_f32(float32x4_t a) {
   return vreinterpretq_u8_f32(a);
 }
 
-// CHECK: test_vreinterpretq_u8_p8
+// CHECK-LABEL: test_vreinterpretq_u8_p8
 uint8x16_t test_vreinterpretq_u8_p8(poly8x16_t a) {
   return vreinterpretq_u8_p8(a);
 }
 
-// CHECK: test_vreinterpretq_u8_p16
+// CHECK-LABEL: test_vreinterpretq_u8_p16
 uint8x16_t test_vreinterpretq_u8_p16(poly16x8_t a) {
   return vreinterpretq_u8_p16(a);
 }
 
-// CHECK: test_vreinterpretq_u16_s8
+// CHECK-LABEL: test_vreinterpretq_u16_s8
 uint16x8_t test_vreinterpretq_u16_s8(int8x16_t a) {
   return vreinterpretq_u16_s8(a);
 }
 
-// CHECK: test_vreinterpretq_u16_s16
+// CHECK-LABEL: test_vreinterpretq_u16_s16
 uint16x8_t test_vreinterpretq_u16_s16(int16x8_t a) {
   return vreinterpretq_u16_s16(a);
 }
 
-// CHECK: test_vreinterpretq_u16_s32
+// CHECK-LABEL: test_vreinterpretq_u16_s32
 uint16x8_t test_vreinterpretq_u16_s32(int32x4_t a) {
   return vreinterpretq_u16_s32(a);
 }
 
-// CHECK: test_vreinterpretq_u16_s64
+// CHECK-LABEL: test_vreinterpretq_u16_s64
 uint16x8_t test_vreinterpretq_u16_s64(int64x2_t a) {
   return vreinterpretq_u16_s64(a);
 }
 
-// CHECK: test_vreinterpretq_u16_u8
+// CHECK-LABEL: test_vreinterpretq_u16_u8
 uint16x8_t test_vreinterpretq_u16_u8(uint8x16_t a) {
   return vreinterpretq_u16_u8(a);
 }
 
-// CHECK: test_vreinterpretq_u16_u32
+// CHECK-LABEL: test_vreinterpretq_u16_u32
 uint16x8_t test_vreinterpretq_u16_u32(uint32x4_t a) {
   return vreinterpretq_u16_u32(a);
 }
 
-// CHECK: test_vreinterpretq_u16_u64
+// CHECK-LABEL: test_vreinterpretq_u16_u64
 uint16x8_t test_vreinterpretq_u16_u64(uint64x2_t a) {
   return vreinterpretq_u16_u64(a);
 }
 
-// CHECK: test_vreinterpretq_u16_f16
+// CHECK-LABEL: test_vreinterpretq_u16_f16
 uint16x8_t test_vreinterpretq_u16_f16(float16x8_t a) {
   return vreinterpretq_u16_f16(a);
 }
 
-// CHECK: test_vreinterpretq_u16_f32
+// CHECK-LABEL: test_vreinterpretq_u16_f32
 uint16x8_t test_vreinterpretq_u16_f32(float32x4_t a) {
   return vreinterpretq_u16_f32(a);
 }
 
-// CHECK: test_vreinterpretq_u16_p8
+// CHECK-LABEL: test_vreinterpretq_u16_p8
 uint16x8_t test_vreinterpretq_u16_p8(poly8x16_t a) {
   return vreinterpretq_u16_p8(a);
 }
 
-// CHECK: test_vreinterpretq_u16_p16
+// CHECK-LABEL: test_vreinterpretq_u16_p16
 uint16x8_t test_vreinterpretq_u16_p16(poly16x8_t a) {
   return vreinterpretq_u16_p16(a);
 }
 
-// CHECK: test_vreinterpretq_u32_s8
+// CHECK-LABEL: test_vreinterpretq_u32_s8
 uint32x4_t test_vreinterpretq_u32_s8(int8x16_t a) {
   return vreinterpretq_u32_s8(a);
 }
 
-// CHECK: test_vreinterpretq_u32_s16
+// CHECK-LABEL: test_vreinterpretq_u32_s16
 uint32x4_t test_vreinterpretq_u32_s16(int16x8_t a) {
   return vreinterpretq_u32_s16(a);
 }
 
-// CHECK: test_vreinterpretq_u32_s32
+// CHECK-LABEL: test_vreinterpretq_u32_s32
 uint32x4_t test_vreinterpretq_u32_s32(int32x4_t a) {
   return vreinterpretq_u32_s32(a);
 }
 
-// CHECK: test_vreinterpretq_u32_s64
+// CHECK-LABEL: test_vreinterpretq_u32_s64
 uint32x4_t test_vreinterpretq_u32_s64(int64x2_t a) {
   return vreinterpretq_u32_s64(a);
 }
 
-// CHECK: test_vreinterpretq_u32_u8
+// CHECK-LABEL: test_vreinterpretq_u32_u8
 uint32x4_t test_vreinterpretq_u32_u8(uint8x16_t a) {
   return vreinterpretq_u32_u8(a);
 }
 
-// CHECK: test_vreinterpretq_u32_u16
+// CHECK-LABEL: test_vreinterpretq_u32_u16
 uint32x4_t test_vreinterpretq_u32_u16(uint16x8_t a) {
   return vreinterpretq_u32_u16(a);
 }
 
-// CHECK: test_vreinterpretq_u32_u64
+// CHECK-LABEL: test_vreinterpretq_u32_u64
 uint32x4_t test_vreinterpretq_u32_u64(uint64x2_t a) {
   return vreinterpretq_u32_u64(a);
 }
 
-// CHECK: test_vreinterpretq_u32_f16
+// CHECK-LABEL: test_vreinterpretq_u32_f16
 uint32x4_t test_vreinterpretq_u32_f16(float16x8_t a) {
   return vreinterpretq_u32_f16(a);
 }
 
-// CHECK: test_vreinterpretq_u32_f32
+// CHECK-LABEL: test_vreinterpretq_u32_f32
 uint32x4_t test_vreinterpretq_u32_f32(float32x4_t a) {
   return vreinterpretq_u32_f32(a);
 }
 
-// CHECK: test_vreinterpretq_u32_p8
+// CHECK-LABEL: test_vreinterpretq_u32_p8
 uint32x4_t test_vreinterpretq_u32_p8(poly8x16_t a) {
   return vreinterpretq_u32_p8(a);
 }
 
-// CHECK: test_vreinterpretq_u32_p16
+// CHECK-LABEL: test_vreinterpretq_u32_p16
 uint32x4_t test_vreinterpretq_u32_p16(poly16x8_t a) {
   return vreinterpretq_u32_p16(a);
 }
 
-// CHECK: test_vreinterpretq_u64_s8
+// CHECK-LABEL: test_vreinterpretq_u64_s8
 uint64x2_t test_vreinterpretq_u64_s8(int8x16_t a) {
   return vreinterpretq_u64_s8(a);
 }
 
-// CHECK: test_vreinterpretq_u64_s16
+// CHECK-LABEL: test_vreinterpretq_u64_s16
 uint64x2_t test_vreinterpretq_u64_s16(int16x8_t a) {
   return vreinterpretq_u64_s16(a);
 }
 
-// CHECK: test_vreinterpretq_u64_s32
+// CHECK-LABEL: test_vreinterpretq_u64_s32
 uint64x2_t test_vreinterpretq_u64_s32(int32x4_t a) {
   return vreinterpretq_u64_s32(a);
 }
 
-// CHECK: test_vreinterpretq_u64_s64
+// CHECK-LABEL: test_vreinterpretq_u64_s64
 uint64x2_t test_vreinterpretq_u64_s64(int64x2_t a) {
   return vreinterpretq_u64_s64(a);
 }
 
-// CHECK: test_vreinterpretq_u64_u8
+// CHECK-LABEL: test_vreinterpretq_u64_u8
 uint64x2_t test_vreinterpretq_u64_u8(uint8x16_t a) {
   return vreinterpretq_u64_u8(a);
 }
 
-// CHECK: test_vreinterpretq_u64_u16
+// CHECK-LABEL: test_vreinterpretq_u64_u16
 uint64x2_t test_vreinterpretq_u64_u16(uint16x8_t a) {
   return vreinterpretq_u64_u16(a);
 }
 
-// CHECK: test_vreinterpretq_u64_u32
+// CHECK-LABEL: test_vreinterpretq_u64_u32
 uint64x2_t test_vreinterpretq_u64_u32(uint32x4_t a) {
   return vreinterpretq_u64_u32(a);
 }
 
-// CHECK: test_vreinterpretq_u64_f16
+// CHECK-LABEL: test_vreinterpretq_u64_f16
 uint64x2_t test_vreinterpretq_u64_f16(float16x8_t a) {
   return vreinterpretq_u64_f16(a);
 }
 
-// CHECK: test_vreinterpretq_u64_f32
+// CHECK-LABEL: test_vreinterpretq_u64_f32
 uint64x2_t test_vreinterpretq_u64_f32(float32x4_t a) {
   return vreinterpretq_u64_f32(a);
 }
 
-// CHECK: test_vreinterpretq_u64_p8
+// CHECK-LABEL: test_vreinterpretq_u64_p8
 uint64x2_t test_vreinterpretq_u64_p8(poly8x16_t a) {
   return vreinterpretq_u64_p8(a);
 }
 
-// CHECK: test_vreinterpretq_u64_p16
+// CHECK-LABEL: test_vreinterpretq_u64_p16
 uint64x2_t test_vreinterpretq_u64_p16(poly16x8_t a) {
   return vreinterpretq_u64_p16(a);
 }
 
-// CHECK: test_vreinterpretq_f16_s8
+// CHECK-LABEL: test_vreinterpretq_f16_s8
 float16x8_t test_vreinterpretq_f16_s8(int8x16_t a) {
   return vreinterpretq_f16_s8(a);
 }
 
-// CHECK: test_vreinterpretq_f16_s16
+// CHECK-LABEL: test_vreinterpretq_f16_s16
 float16x8_t test_vreinterpretq_f16_s16(int16x8_t a) {
   return vreinterpretq_f16_s16(a);
 }
 
-// CHECK: test_vreinterpretq_f16_s32
+// CHECK-LABEL: test_vreinterpretq_f16_s32
 float16x8_t test_vreinterpretq_f16_s32(int32x4_t a) {
   return vreinterpretq_f16_s32(a);
 }
 
-// CHECK: test_vreinterpretq_f16_s64
+// CHECK-LABEL: test_vreinterpretq_f16_s64
 float16x8_t test_vreinterpretq_f16_s64(int64x2_t a) {
   return vreinterpretq_f16_s64(a);
 }
 
-// CHECK: test_vreinterpretq_f16_u8
+// CHECK-LABEL: test_vreinterpretq_f16_u8
 float16x8_t test_vreinterpretq_f16_u8(uint8x16_t a) {
   return vreinterpretq_f16_u8(a);
 }
 
-// CHECK: test_vreinterpretq_f16_u16
+// CHECK-LABEL: test_vreinterpretq_f16_u16
 float16x8_t test_vreinterpretq_f16_u16(uint16x8_t a) {
   return vreinterpretq_f16_u16(a);
 }
 
-// CHECK: test_vreinterpretq_f16_u32
+// CHECK-LABEL: test_vreinterpretq_f16_u32
 float16x8_t test_vreinterpretq_f16_u32(uint32x4_t a) {
   return vreinterpretq_f16_u32(a);
 }
 
-// CHECK: test_vreinterpretq_f16_u64
+// CHECK-LABEL: test_vreinterpretq_f16_u64
 float16x8_t test_vreinterpretq_f16_u64(uint64x2_t a) {
   return vreinterpretq_f16_u64(a);
 }
 
-// CHECK: test_vreinterpretq_f16_f32
+// CHECK-LABEL: test_vreinterpretq_f16_f32
 float16x8_t test_vreinterpretq_f16_f32(float32x4_t a) {
   return vreinterpretq_f16_f32(a);
 }
 
-// CHECK: test_vreinterpretq_f16_p8
+// CHECK-LABEL: test_vreinterpretq_f16_p8
 float16x8_t test_vreinterpretq_f16_p8(poly8x16_t a) {
   return vreinterpretq_f16_p8(a);
 }
 
-// CHECK: test_vreinterpretq_f16_p16
+// CHECK-LABEL: test_vreinterpretq_f16_p16
 float16x8_t test_vreinterpretq_f16_p16(poly16x8_t a) {
   return vreinterpretq_f16_p16(a);
 }
 
-// CHECK: test_vreinterpretq_f32_s8
+// CHECK-LABEL: test_vreinterpretq_f32_s8
 float32x4_t test_vreinterpretq_f32_s8(int8x16_t a) {
   return vreinterpretq_f32_s8(a);
 }
 
-// CHECK: test_vreinterpretq_f32_s16
+// CHECK-LABEL: test_vreinterpretq_f32_s16
 float32x4_t test_vreinterpretq_f32_s16(int16x8_t a) {
   return vreinterpretq_f32_s16(a);
 }
 
-// CHECK: test_vreinterpretq_f32_s32
+// CHECK-LABEL: test_vreinterpretq_f32_s32
 float32x4_t test_vreinterpretq_f32_s32(int32x4_t a) {
   return vreinterpretq_f32_s32(a);
 }
 
-// CHECK: test_vreinterpretq_f32_s64
+// CHECK-LABEL: test_vreinterpretq_f32_s64
 float32x4_t test_vreinterpretq_f32_s64(int64x2_t a) {
   return vreinterpretq_f32_s64(a);
 }
 
-// CHECK: test_vreinterpretq_f32_u8
+// CHECK-LABEL: test_vreinterpretq_f32_u8
 float32x4_t test_vreinterpretq_f32_u8(uint8x16_t a) {
   return vreinterpretq_f32_u8(a);
 }
 
-// CHECK: test_vreinterpretq_f32_u16
+// CHECK-LABEL: test_vreinterpretq_f32_u16
 float32x4_t test_vreinterpretq_f32_u16(uint16x8_t a) {
   return vreinterpretq_f32_u16(a);
 }
 
-// CHECK: test_vreinterpretq_f32_u32
+// CHECK-LABEL: test_vreinterpretq_f32_u32
 float32x4_t test_vreinterpretq_f32_u32(uint32x4_t a) {
   return vreinterpretq_f32_u32(a);
 }
 
-// CHECK: test_vreinterpretq_f32_u64
+// CHECK-LABEL: test_vreinterpretq_f32_u64
 float32x4_t test_vreinterpretq_f32_u64(uint64x2_t a) {
   return vreinterpretq_f32_u64(a);
 }
 
-// CHECK: test_vreinterpretq_f32_f16
+// CHECK-LABEL: test_vreinterpretq_f32_f16
 float32x4_t test_vreinterpretq_f32_f16(float16x8_t a) {
   return vreinterpretq_f32_f16(a);
 }
 
-// CHECK: test_vreinterpretq_f32_p8
+// CHECK-LABEL: test_vreinterpretq_f32_p8
 float32x4_t test_vreinterpretq_f32_p8(poly8x16_t a) {
   return vreinterpretq_f32_p8(a);
 }
 
-// CHECK: test_vreinterpretq_f32_p16
+// CHECK-LABEL: test_vreinterpretq_f32_p16
 float32x4_t test_vreinterpretq_f32_p16(poly16x8_t a) {
   return vreinterpretq_f32_p16(a);
 }
 
-// CHECK: test_vreinterpretq_p8_s8
+// CHECK-LABEL: test_vreinterpretq_p8_s8
 poly8x16_t test_vreinterpretq_p8_s8(int8x16_t a) {
   return vreinterpretq_p8_s8(a);
 }
 
-// CHECK: test_vreinterpretq_p8_s16
+// CHECK-LABEL: test_vreinterpretq_p8_s16
 poly8x16_t test_vreinterpretq_p8_s16(int16x8_t a) {
   return vreinterpretq_p8_s16(a);
 }
 
-// CHECK: test_vreinterpretq_p8_s32
+// CHECK-LABEL: test_vreinterpretq_p8_s32
 poly8x16_t test_vreinterpretq_p8_s32(int32x4_t a) {
   return vreinterpretq_p8_s32(a);
 }
 
-// CHECK: test_vreinterpretq_p8_s64
+// CHECK-LABEL: test_vreinterpretq_p8_s64
 poly8x16_t test_vreinterpretq_p8_s64(int64x2_t a) {
   return vreinterpretq_p8_s64(a);
 }
 
-// CHECK: test_vreinterpretq_p8_u8
+// CHECK-LABEL: test_vreinterpretq_p8_u8
 poly8x16_t test_vreinterpretq_p8_u8(uint8x16_t a) {
   return vreinterpretq_p8_u8(a);
 }
 
-// CHECK: test_vreinterpretq_p8_u16
+// CHECK-LABEL: test_vreinterpretq_p8_u16
 poly8x16_t test_vreinterpretq_p8_u16(uint16x8_t a) {
   return vreinterpretq_p8_u16(a);
 }
 
-// CHECK: test_vreinterpretq_p8_u32
+// CHECK-LABEL: test_vreinterpretq_p8_u32
 poly8x16_t test_vreinterpretq_p8_u32(uint32x4_t a) {
   return vreinterpretq_p8_u32(a);
 }
 
-// CHECK: test_vreinterpretq_p8_u64
+// CHECK-LABEL: test_vreinterpretq_p8_u64
 poly8x16_t test_vreinterpretq_p8_u64(uint64x2_t a) {
   return vreinterpretq_p8_u64(a);
 }
 
-// CHECK: test_vreinterpretq_p8_f16
+// CHECK-LABEL: test_vreinterpretq_p8_f16
 poly8x16_t test_vreinterpretq_p8_f16(float16x8_t a) {
   return vreinterpretq_p8_f16(a);
 }
 
-// CHECK: test_vreinterpretq_p8_f32
+// CHECK-LABEL: test_vreinterpretq_p8_f32
 poly8x16_t test_vreinterpretq_p8_f32(float32x4_t a) {
   return vreinterpretq_p8_f32(a);
 }
 
-// CHECK: test_vreinterpretq_p8_p16
+// CHECK-LABEL: test_vreinterpretq_p8_p16
 poly8x16_t test_vreinterpretq_p8_p16(poly16x8_t a) {
   return vreinterpretq_p8_p16(a);
 }
 
-// CHECK: test_vreinterpretq_p16_s8
+// CHECK-LABEL: test_vreinterpretq_p16_s8
 poly16x8_t test_vreinterpretq_p16_s8(int8x16_t a) {
   return vreinterpretq_p16_s8(a);
 }
 
-// CHECK: test_vreinterpretq_p16_s16
+// CHECK-LABEL: test_vreinterpretq_p16_s16
 poly16x8_t test_vreinterpretq_p16_s16(int16x8_t a) {
   return vreinterpretq_p16_s16(a);
 }
 
-// CHECK: test_vreinterpretq_p16_s32
+// CHECK-LABEL: test_vreinterpretq_p16_s32
 poly16x8_t test_vreinterpretq_p16_s32(int32x4_t a) {
   return vreinterpretq_p16_s32(a);
 }
 
-// CHECK: test_vreinterpretq_p16_s64
+// CHECK-LABEL: test_vreinterpretq_p16_s64
 poly16x8_t test_vreinterpretq_p16_s64(int64x2_t a) {
   return vreinterpretq_p16_s64(a);
 }
 
-// CHECK: test_vreinterpretq_p16_u8
+// CHECK-LABEL: test_vreinterpretq_p16_u8
 poly16x8_t test_vreinterpretq_p16_u8(uint8x16_t a) {
   return vreinterpretq_p16_u8(a);
 }
 
-// CHECK: test_vreinterpretq_p16_u16
+// CHECK-LABEL: test_vreinterpretq_p16_u16
 poly16x8_t test_vreinterpretq_p16_u16(uint16x8_t a) {
   return vreinterpretq_p16_u16(a);
 }
 
-// CHECK: test_vreinterpretq_p16_u32
+// CHECK-LABEL: test_vreinterpretq_p16_u32
 poly16x8_t test_vreinterpretq_p16_u32(uint32x4_t a) {
   return vreinterpretq_p16_u32(a);
 }
 
-// CHECK: test_vreinterpretq_p16_u64
+// CHECK-LABEL: test_vreinterpretq_p16_u64
 poly16x8_t test_vreinterpretq_p16_u64(uint64x2_t a) {
   return vreinterpretq_p16_u64(a);
 }
 
-// CHECK: test_vreinterpretq_p16_f16
+// CHECK-LABEL: test_vreinterpretq_p16_f16
 poly16x8_t test_vreinterpretq_p16_f16(float16x8_t a) {
   return vreinterpretq_p16_f16(a);
 }
 
-// CHECK: test_vreinterpretq_p16_f32
+// CHECK-LABEL: test_vreinterpretq_p16_f32
 poly16x8_t test_vreinterpretq_p16_f32(float32x4_t a) {
   return vreinterpretq_p16_f32(a);
 }
 
-// CHECK: test_vreinterpretq_p16_p8
+// CHECK-LABEL: test_vreinterpretq_p16_p8
 poly16x8_t test_vreinterpretq_p16_p8(poly8x16_t a) {
   return vreinterpretq_p16_p8(a);
 }
 
 
-// CHECK: test_vrev16_s8
+// CHECK-LABEL: test_vrev16_s8
 // CHECK: vrev16.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrev16_s8(int8x8_t a) {
   return vrev16_s8(a);
 }
 
-// CHECK: test_vrev16_u8
+// CHECK-LABEL: test_vrev16_u8
 // CHECK: vrev16.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrev16_u8(uint8x8_t a) {
   return vrev16_u8(a);
 }
 
-// CHECK: test_vrev16_p8
+// CHECK-LABEL: test_vrev16_p8
 // CHECK: vrev16.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vrev16_p8(poly8x8_t a) {
   return vrev16_p8(a);
 }
 
-// CHECK: test_vrev16q_s8
+// CHECK-LABEL: test_vrev16q_s8
 // CHECK: vrev16.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrev16q_s8(int8x16_t a) {
   return vrev16q_s8(a);
 }
 
-// CHECK: test_vrev16q_u8
+// CHECK-LABEL: test_vrev16q_u8
 // CHECK: vrev16.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrev16q_u8(uint8x16_t a) {
   return vrev16q_u8(a);
 }
 
-// CHECK: test_vrev16q_p8
+// CHECK-LABEL: test_vrev16q_p8
 // CHECK: vrev16.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vrev16q_p8(poly8x16_t a) {
   return vrev16q_p8(a);
 }
 
 
-// CHECK: test_vrev32_s8
+// CHECK-LABEL: test_vrev32_s8
 // CHECK: vrev32.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrev32_s8(int8x8_t a) {
   return vrev32_s8(a);
 }
 
-// CHECK: test_vrev32_s16
+// CHECK-LABEL: test_vrev32_s16
 // CHECK: vrev32.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vrev32_s16(int16x4_t a) {
   return vrev32_s16(a);
 }
 
-// CHECK: test_vrev32_u8
+// CHECK-LABEL: test_vrev32_u8
 // CHECK: vrev32.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrev32_u8(uint8x8_t a) {
   return vrev32_u8(a);
 }
 
-// CHECK: test_vrev32_u16
+// CHECK-LABEL: test_vrev32_u16
 // CHECK: vrev32.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vrev32_u16(uint16x4_t a) {
   return vrev32_u16(a);
 }
 
-// CHECK: test_vrev32_p8
+// CHECK-LABEL: test_vrev32_p8
 // CHECK: vrev32.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vrev32_p8(poly8x8_t a) {
   return vrev32_p8(a);
 }
 
-// CHECK: test_vrev32_p16
+// CHECK-LABEL: test_vrev32_p16
 // CHECK: vrev32.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4_t test_vrev32_p16(poly16x4_t a) {
   return vrev32_p16(a);
 }
 
-// CHECK: test_vrev32q_s8
+// CHECK-LABEL: test_vrev32q_s8
 // CHECK: vrev32.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrev32q_s8(int8x16_t a) {
   return vrev32q_s8(a);
 }
 
-// CHECK: test_vrev32q_s16
+// CHECK-LABEL: test_vrev32q_s16
 // CHECK: vrev32.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vrev32q_s16(int16x8_t a) {
   return vrev32q_s16(a);
 }
 
-// CHECK: test_vrev32q_u8
+// CHECK-LABEL: test_vrev32q_u8
 // CHECK: vrev32.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrev32q_u8(uint8x16_t a) {
   return vrev32q_u8(a);
 }
 
-// CHECK: test_vrev32q_u16
+// CHECK-LABEL: test_vrev32q_u16
 // CHECK: vrev32.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vrev32q_u16(uint16x8_t a) {
   return vrev32q_u16(a);
 }
 
-// CHECK: test_vrev32q_p8
+// CHECK-LABEL: test_vrev32q_p8
 // CHECK: vrev32.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vrev32q_p8(poly8x16_t a) {
   return vrev32q_p8(a);
 }
 
-// CHECK: test_vrev32q_p16
+// CHECK-LABEL: test_vrev32q_p16
 // CHECK: vrev32.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8_t test_vrev32q_p16(poly16x8_t a) {
   return vrev32q_p16(a);
 }
 
 
-// CHECK: test_vrev64_s8
+// CHECK-LABEL: test_vrev64_s8
 // CHECK: vrev64.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrev64_s8(int8x8_t a) {
   return vrev64_s8(a);
 }
 
-// CHECK: test_vrev64_s16
+// CHECK-LABEL: test_vrev64_s16
 // CHECK: vrev64.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vrev64_s16(int16x4_t a) {
   return vrev64_s16(a);
 }
 
-// CHECK: test_vrev64_s32
+// CHECK-LABEL: test_vrev64_s32
 // CHECK: vrev64.32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vrev64_s32(int32x2_t a) {
   return vrev64_s32(a);
 }
 
-// CHECK: test_vrev64_u8
+// CHECK-LABEL: test_vrev64_u8
 // CHECK: vrev64.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrev64_u8(uint8x8_t a) {
   return vrev64_u8(a);
 }
 
-// CHECK: test_vrev64_u16
+// CHECK-LABEL: test_vrev64_u16
 // CHECK: vrev64.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vrev64_u16(uint16x4_t a) {
   return vrev64_u16(a);
 }
 
-// CHECK: test_vrev64_u32
+// CHECK-LABEL: test_vrev64_u32
 // CHECK: vrev64.32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrev64_u32(uint32x2_t a) {
   return vrev64_u32(a);
 }
 
-// CHECK: test_vrev64_p8
+// CHECK-LABEL: test_vrev64_p8
 // CHECK: vrev64.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vrev64_p8(poly8x8_t a) {
   return vrev64_p8(a);
 }
 
-// CHECK: test_vrev64_p16
+// CHECK-LABEL: test_vrev64_p16
 // CHECK: vrev64.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4_t test_vrev64_p16(poly16x4_t a) {
   return vrev64_p16(a);
 }
 
-// CHECK: test_vrev64_f32
+// CHECK-LABEL: test_vrev64_f32
 // CHECK: vrev64.32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrev64_f32(float32x2_t a) {
   return vrev64_f32(a);
 }
 
-// CHECK: test_vrev64q_s8
+// CHECK-LABEL: test_vrev64q_s8
 // CHECK: vrev64.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrev64q_s8(int8x16_t a) {
   return vrev64q_s8(a);
 }
 
-// CHECK: test_vrev64q_s16
+// CHECK-LABEL: test_vrev64q_s16
 // CHECK: vrev64.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vrev64q_s16(int16x8_t a) {
   return vrev64q_s16(a);
 }
 
-// CHECK: test_vrev64q_s32
+// CHECK-LABEL: test_vrev64q_s32
 // CHECK: vrev64.32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vrev64q_s32(int32x4_t a) {
   return vrev64q_s32(a);
 }
 
-// CHECK: test_vrev64q_u8
+// CHECK-LABEL: test_vrev64q_u8
 // CHECK: vrev64.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrev64q_u8(uint8x16_t a) {
   return vrev64q_u8(a);
 }
 
-// CHECK: test_vrev64q_u16
+// CHECK-LABEL: test_vrev64q_u16
 // CHECK: vrev64.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vrev64q_u16(uint16x8_t a) {
   return vrev64q_u16(a);
 }
 
-// CHECK: test_vrev64q_u32
+// CHECK-LABEL: test_vrev64q_u32
 // CHECK: vrev64.32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrev64q_u32(uint32x4_t a) {
   return vrev64q_u32(a);
 }
 
-// CHECK: test_vrev64q_p8
+// CHECK-LABEL: test_vrev64q_p8
 // CHECK: vrev64.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vrev64q_p8(poly8x16_t a) {
   return vrev64q_p8(a);
 }
 
-// CHECK: test_vrev64q_p16
+// CHECK-LABEL: test_vrev64q_p16
 // CHECK: vrev64.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8_t test_vrev64q_p16(poly16x8_t a) {
   return vrev64q_p16(a);
 }
 
-// CHECK: test_vrev64q_f32
+// CHECK-LABEL: test_vrev64q_f32
 // CHECK: vrev64.32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrev64q_f32(float32x4_t a) {
   return vrev64q_f32(a);
 }
 
 
-// CHECK: test_vrhadd_s8
+// CHECK-LABEL: test_vrhadd_s8
 // CHECK: vrhadd.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrhadd_s8(int8x8_t a, int8x8_t b) {
   return vrhadd_s8(a, b);
 }
 
-// CHECK: test_vrhadd_s16
+// CHECK-LABEL: test_vrhadd_s16
 // CHECK: vrhadd.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vrhadd_s16(int16x4_t a, int16x4_t b) {
   return vrhadd_s16(a, b);
 }
 
-// CHECK: test_vrhadd_s32
+// CHECK-LABEL: test_vrhadd_s32
 // CHECK: vrhadd.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vrhadd_s32(int32x2_t a, int32x2_t b) {
   return vrhadd_s32(a, b);
 }
 
-// CHECK: test_vrhadd_u8
+// CHECK-LABEL: test_vrhadd_u8
 // CHECK: vrhadd.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrhadd_u8(uint8x8_t a, uint8x8_t b) {
   return vrhadd_u8(a, b);
 }
 
-// CHECK: test_vrhadd_u16
+// CHECK-LABEL: test_vrhadd_u16
 // CHECK: vrhadd.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vrhadd_u16(uint16x4_t a, uint16x4_t b) {
   return vrhadd_u16(a, b);
 }
 
-// CHECK: test_vrhadd_u32
+// CHECK-LABEL: test_vrhadd_u32
 // CHECK: vrhadd.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrhadd_u32(uint32x2_t a, uint32x2_t b) {
   return vrhadd_u32(a, b);
 }
 
-// CHECK: test_vrhaddq_s8
+// CHECK-LABEL: test_vrhaddq_s8
 // CHECK: vrhadd.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrhaddq_s8(int8x16_t a, int8x16_t b) {
   return vrhaddq_s8(a, b);
 }
 
-// CHECK: test_vrhaddq_s16
+// CHECK-LABEL: test_vrhaddq_s16
 // CHECK: vrhadd.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vrhaddq_s16(int16x8_t a, int16x8_t b) {
   return vrhaddq_s16(a, b);
 }
 
-// CHECK: test_vrhaddq_s32
+// CHECK-LABEL: test_vrhaddq_s32
 // CHECK: vrhadd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vrhaddq_s32(int32x4_t a, int32x4_t b) {
   return vrhaddq_s32(a, b);
 }
 
-// CHECK: test_vrhaddq_u8
+// CHECK-LABEL: test_vrhaddq_u8
 // CHECK: vrhadd.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrhaddq_u8(uint8x16_t a, uint8x16_t b) {
   return vrhaddq_u8(a, b);
 }
 
-// CHECK: test_vrhaddq_u16
+// CHECK-LABEL: test_vrhaddq_u16
 // CHECK: vrhadd.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vrhaddq_u16(uint16x8_t a, uint16x8_t b) {
   return vrhaddq_u16(a, b);
 }
 
-// CHECK: test_vrhaddq_u32
+// CHECK-LABEL: test_vrhaddq_u32
 // CHECK: vrhadd.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrhaddq_u32(uint32x4_t a, uint32x4_t b) {
   return vrhaddq_u32(a, b);
 }
 
 
-// CHECK: test_vrshl_s8
+// CHECK-LABEL: test_vrshl_s8
 // CHECK: vrshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrshl_s8(int8x8_t a, int8x8_t b) {
   return vrshl_s8(a, b);
 }
 
-// CHECK: test_vrshl_s16
+// CHECK-LABEL: test_vrshl_s16
 // CHECK: vrshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vrshl_s16(int16x4_t a, int16x4_t b) {
   return vrshl_s16(a, b);
 }
 
-// CHECK: test_vrshl_s32
+// CHECK-LABEL: test_vrshl_s32
 // CHECK: vrshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vrshl_s32(int32x2_t a, int32x2_t b) {
   return vrshl_s32(a, b);
 }
 
-// CHECK: test_vrshl_s64
+// CHECK-LABEL: test_vrshl_s64
 // CHECK: vrshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vrshl_s64(int64x1_t a, int64x1_t b) {
   return vrshl_s64(a, b);
 }
 
-// CHECK: test_vrshl_u8
+// CHECK-LABEL: test_vrshl_u8
 // CHECK: vrshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrshl_u8(uint8x8_t a, int8x8_t b) {
   return vrshl_u8(a, b);
 }
 
-// CHECK: test_vrshl_u16
+// CHECK-LABEL: test_vrshl_u16
 // CHECK: vrshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vrshl_u16(uint16x4_t a, int16x4_t b) {
   return vrshl_u16(a, b);
 }
 
-// CHECK: test_vrshl_u32
+// CHECK-LABEL: test_vrshl_u32
 // CHECK: vrshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrshl_u32(uint32x2_t a, int32x2_t b) {
   return vrshl_u32(a, b);
 }
 
-// CHECK: test_vrshl_u64
+// CHECK-LABEL: test_vrshl_u64
 // CHECK: vrshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vrshl_u64(uint64x1_t a, int64x1_t b) {
   return vrshl_u64(a, b);
 }
 
-// CHECK: test_vrshlq_s8
+// CHECK-LABEL: test_vrshlq_s8
 // CHECK: vrshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrshlq_s8(int8x16_t a, int8x16_t b) {
   return vrshlq_s8(a, b);
 }
 
-// CHECK: test_vrshlq_s16
+// CHECK-LABEL: test_vrshlq_s16
 // CHECK: vrshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vrshlq_s16(int16x8_t a, int16x8_t b) {
   return vrshlq_s16(a, b);
 }
 
-// CHECK: test_vrshlq_s32
+// CHECK-LABEL: test_vrshlq_s32
 // CHECK: vrshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vrshlq_s32(int32x4_t a, int32x4_t b) {
   return vrshlq_s32(a, b);
 }
 
-// CHECK: test_vrshlq_s64
+// CHECK-LABEL: test_vrshlq_s64
 // CHECK: vrshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vrshlq_s64(int64x2_t a, int64x2_t b) {
   return vrshlq_s64(a, b);
 }
 
-// CHECK: test_vrshlq_u8
+// CHECK-LABEL: test_vrshlq_u8
 // CHECK: vrshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrshlq_u8(uint8x16_t a, int8x16_t b) {
   return vrshlq_u8(a, b);
 }
 
-// CHECK: test_vrshlq_u16
+// CHECK-LABEL: test_vrshlq_u16
 // CHECK: vrshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vrshlq_u16(uint16x8_t a, int16x8_t b) {
   return vrshlq_u16(a, b);
 }
 
-// CHECK: test_vrshlq_u32
+// CHECK-LABEL: test_vrshlq_u32
 // CHECK: vrshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrshlq_u32(uint32x4_t a, int32x4_t b) {
   return vrshlq_u32(a, b);
 }
 
-// CHECK: test_vrshlq_u64
+// CHECK-LABEL: test_vrshlq_u64
 // CHECK: vrshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vrshlq_u64(uint64x2_t a, int64x2_t b) {
   return vrshlq_u64(a, b);
 }
 
 
-// CHECK: test_vrshrn_n_s16
+// CHECK-LABEL: test_vrshrn_n_s16
 // CHECK: vrshrn.i16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vrshrn_n_s16(int16x8_t a) {
   return vrshrn_n_s16(a, 1);
 }
 
-// CHECK: test_vrshrn_n_s32
+// CHECK-LABEL: test_vrshrn_n_s32
 // CHECK: vrshrn.i32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vrshrn_n_s32(int32x4_t a) {
   return vrshrn_n_s32(a, 1);
 }
 
-// CHECK: test_vrshrn_n_s64
+// CHECK-LABEL: test_vrshrn_n_s64
 // CHECK: vrshrn.i64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vrshrn_n_s64(int64x2_t a) {
   return vrshrn_n_s64(a, 1);
 }
 
-// CHECK: test_vrshrn_n_u16
+// CHECK-LABEL: test_vrshrn_n_u16
 // CHECK: vrshrn.i16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vrshrn_n_u16(uint16x8_t a) {
   return vrshrn_n_u16(a, 1);
 }
 
-// CHECK: test_vrshrn_n_u32
+// CHECK-LABEL: test_vrshrn_n_u32
 // CHECK: vrshrn.i32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vrshrn_n_u32(uint32x4_t a) {
   return vrshrn_n_u32(a, 1);
 }
 
-// CHECK: test_vrshrn_n_u64
+// CHECK-LABEL: test_vrshrn_n_u64
 // CHECK: vrshrn.i64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vrshrn_n_u64(uint64x2_t a) {
   return vrshrn_n_u64(a, 1);
 }
 
 
-// CHECK: test_vrshr_n_s8
+// CHECK-LABEL: test_vrshr_n_s8
 // CHECK: vrshr.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vrshr_n_s8(int8x8_t a) {
   return vrshr_n_s8(a, 1);
 }
 
-// CHECK: test_vrshr_n_s16
+// CHECK-LABEL: test_vrshr_n_s16
 // CHECK: vrshr.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vrshr_n_s16(int16x4_t a) {
   return vrshr_n_s16(a, 1);
 }
 
-// CHECK: test_vrshr_n_s32
+// CHECK-LABEL: test_vrshr_n_s32
 // CHECK: vrshr.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vrshr_n_s32(int32x2_t a) {
   return vrshr_n_s32(a, 1);
 }
 
-// CHECK: test_vrshr_n_s64
+// CHECK-LABEL: test_vrshr_n_s64
 // CHECK: vrshr.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vrshr_n_s64(int64x1_t a) {
   return vrshr_n_s64(a, 1);
 }
 
-// CHECK: test_vrshr_n_u8
+// CHECK-LABEL: test_vrshr_n_u8
 // CHECK: vrshr.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vrshr_n_u8(uint8x8_t a) {
   return vrshr_n_u8(a, 1);
 }
 
-// CHECK: test_vrshr_n_u16
+// CHECK-LABEL: test_vrshr_n_u16
 // CHECK: vrshr.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vrshr_n_u16(uint16x4_t a) {
   return vrshr_n_u16(a, 1);
 }
 
-// CHECK: test_vrshr_n_u32
+// CHECK-LABEL: test_vrshr_n_u32
 // CHECK: vrshr.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vrshr_n_u32(uint32x2_t a) {
   return vrshr_n_u32(a, 1);
 }
 
-// CHECK: test_vrshr_n_u64
+// CHECK-LABEL: test_vrshr_n_u64
 // CHECK: vrshr.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vrshr_n_u64(uint64x1_t a) {
   return vrshr_n_u64(a, 1);
 }
 
-// CHECK: test_vrshrq_n_s8
+// CHECK-LABEL: test_vrshrq_n_s8
 // CHECK: vrshr.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vrshrq_n_s8(int8x16_t a) {
   return vrshrq_n_s8(a, 1);
 }
 
-// CHECK: test_vrshrq_n_s16
+// CHECK-LABEL: test_vrshrq_n_s16
 // CHECK: vrshr.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vrshrq_n_s16(int16x8_t a) {
   return vrshrq_n_s16(a, 1);
 }
 
-// CHECK: test_vrshrq_n_s32
+// CHECK-LABEL: test_vrshrq_n_s32
 // CHECK: vrshr.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vrshrq_n_s32(int32x4_t a) {
   return vrshrq_n_s32(a, 1);
 }
 
-// CHECK: test_vrshrq_n_s64
+// CHECK-LABEL: test_vrshrq_n_s64
 // CHECK: vrshr.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vrshrq_n_s64(int64x2_t a) {
   return vrshrq_n_s64(a, 1);
 }
 
-// CHECK: test_vrshrq_n_u8
+// CHECK-LABEL: test_vrshrq_n_u8
 // CHECK: vrshr.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vrshrq_n_u8(uint8x16_t a) {
   return vrshrq_n_u8(a, 1);
 }
 
-// CHECK: test_vrshrq_n_u16
+// CHECK-LABEL: test_vrshrq_n_u16
 // CHECK: vrshr.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vrshrq_n_u16(uint16x8_t a) {
   return vrshrq_n_u16(a, 1);
 }
 
-// CHECK: test_vrshrq_n_u32
+// CHECK-LABEL: test_vrshrq_n_u32
 // CHECK: vrshr.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vrshrq_n_u32(uint32x4_t a) {
   return vrshrq_n_u32(a, 1);
 }
 
-// CHECK: test_vrshrq_n_u64
+// CHECK-LABEL: test_vrshrq_n_u64
 // CHECK: vrshr.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vrshrq_n_u64(uint64x2_t a) {
   return vrshrq_n_u64(a, 1);
 }
 
 
-// CHECK: test_vrsqrte_f32
+// CHECK-LABEL: test_vrsqrte_f32
 // CHECK: vrsqrte.f32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrsqrte_f32(float32x2_t a) {
   return vrsqrte_f32(a);
 }
 
-// CHECK: test_vrsqrte_u32
+// CHECK-LABEL: test_vrsqrte_u32
 // CHECK: vrsqrte.u32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrsqrte_u32(uint32x2_t a) {
   return vrsqrte_u32(a);
 }
 
-// CHECK: test_vrsqrteq_f32
+// CHECK-LABEL: test_vrsqrteq_f32
 // CHECK: vrsqrte.f32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrsqrteq_f32(float32x4_t a) {
   return vrsqrteq_f32(a);
 }
 
-// CHECK: test_vrsqrteq_u32
+// CHECK-LABEL: test_vrsqrteq_u32
 // CHECK: vrsqrte.u32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrsqrteq_u32(uint32x4_t a) {
   return vrsqrteq_u32(a);
 }
 
 
-// CHECK: test_vrsqrts_f32
+// CHECK-LABEL: test_vrsqrts_f32
 // CHECK: vrsqrts.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrsqrts_f32(float32x2_t a, float32x2_t b) {
   return vrsqrts_f32(a, b);
 }
 
-// CHECK: test_vrsqrtsq_f32
+// CHECK-LABEL: test_vrsqrtsq_f32
 // CHECK: vrsqrts.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrsqrtsq_f32(float32x4_t a, float32x4_t b) {
   return vrsqrtsq_f32(a, b);
 }
 
 
-// CHECK: test_vrsra_n_s8
+// CHECK-LABEL: test_vrsra_n_s8
 // CHECK: vrsra.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vrsra_n_s8(int8x8_t a, int8x8_t b) {
   return vrsra_n_s8(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_s16
+// CHECK-LABEL: test_vrsra_n_s16
 // CHECK: vrsra.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vrsra_n_s16(int16x4_t a, int16x4_t b) {
   return vrsra_n_s16(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_s32
+// CHECK-LABEL: test_vrsra_n_s32
 // CHECK: vrsra.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vrsra_n_s32(int32x2_t a, int32x2_t b) {
   return vrsra_n_s32(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_s64
+// CHECK-LABEL: test_vrsra_n_s64
 // CHECK: vrsra.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vrsra_n_s64(int64x1_t a, int64x1_t b) {
   return vrsra_n_s64(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_u8
+// CHECK-LABEL: test_vrsra_n_u8
 // CHECK: vrsra.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vrsra_n_u8(uint8x8_t a, uint8x8_t b) {
   return vrsra_n_u8(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_u16
+// CHECK-LABEL: test_vrsra_n_u16
 // CHECK: vrsra.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vrsra_n_u16(uint16x4_t a, uint16x4_t b) {
   return vrsra_n_u16(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_u32
+// CHECK-LABEL: test_vrsra_n_u32
 // CHECK: vrsra.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vrsra_n_u32(uint32x2_t a, uint32x2_t b) {
   return vrsra_n_u32(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_u64
+// CHECK-LABEL: test_vrsra_n_u64
 // CHECK: vrsra.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vrsra_n_u64(uint64x1_t a, uint64x1_t b) {
   return vrsra_n_u64(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_s8
+// CHECK-LABEL: test_vrsraq_n_s8
 // CHECK: vrsra.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vrsraq_n_s8(int8x16_t a, int8x16_t b) {
   return vrsraq_n_s8(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_s16
+// CHECK-LABEL: test_vrsraq_n_s16
 // CHECK: vrsra.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vrsraq_n_s16(int16x8_t a, int16x8_t b) {
   return vrsraq_n_s16(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_s32
+// CHECK-LABEL: test_vrsraq_n_s32
 // CHECK: vrsra.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vrsraq_n_s32(int32x4_t a, int32x4_t b) {
   return vrsraq_n_s32(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_s64
+// CHECK-LABEL: test_vrsraq_n_s64
 // CHECK: vrsra.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vrsraq_n_s64(int64x2_t a, int64x2_t b) {
   return vrsraq_n_s64(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_u8
+// CHECK-LABEL: test_vrsraq_n_u8
 // CHECK: vrsra.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vrsraq_n_u8(uint8x16_t a, uint8x16_t b) {
   return vrsraq_n_u8(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_u16
+// CHECK-LABEL: test_vrsraq_n_u16
 // CHECK: vrsra.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vrsraq_n_u16(uint16x8_t a, uint16x8_t b) {
   return vrsraq_n_u16(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_u32
+// CHECK-LABEL: test_vrsraq_n_u32
 // CHECK: vrsra.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vrsraq_n_u32(uint32x4_t a, uint32x4_t b) {
   return vrsraq_n_u32(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_u64
+// CHECK-LABEL: test_vrsraq_n_u64
 // CHECK: vrsra.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vrsraq_n_u64(uint64x2_t a, uint64x2_t b) {
   return vrsraq_n_u64(a, b, 1);
 }
 
 
-// CHECK: test_vrsubhn_s16
+// CHECK-LABEL: test_vrsubhn_s16
 // CHECK: vrsubhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vrsubhn_s16(int16x8_t a, int16x8_t b) {
   return vrsubhn_s16(a, b);
 }
 
-// CHECK: test_vrsubhn_s32
+// CHECK-LABEL: test_vrsubhn_s32
 // CHECK: vrsubhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vrsubhn_s32(int32x4_t a, int32x4_t b) {
   return vrsubhn_s32(a, b);
 }
 
-// CHECK: test_vrsubhn_s64
+// CHECK-LABEL: test_vrsubhn_s64
 // CHECK: vrsubhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vrsubhn_s64(int64x2_t a, int64x2_t b) {
   return vrsubhn_s64(a, b);
 }
 
-// CHECK: test_vrsubhn_u16
+// CHECK-LABEL: test_vrsubhn_u16
 // CHECK: vrsubhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vrsubhn_u16(uint16x8_t a, uint16x8_t b) {
   return vrsubhn_u16(a, b);
 }
 
-// CHECK: test_vrsubhn_u32
+// CHECK-LABEL: test_vrsubhn_u32
 // CHECK: vrsubhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vrsubhn_u32(uint32x4_t a, uint32x4_t b) {
   return vrsubhn_u32(a, b);
 }
 
-// CHECK: test_vrsubhn_u64
+// CHECK-LABEL: test_vrsubhn_u64
 // CHECK: vrsubhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vrsubhn_u64(uint64x2_t a, uint64x2_t b) {
   return vrsubhn_u64(a, b);
 }
 
 
-// CHECK: test_vset_lane_u8
+// CHECK-LABEL: test_vset_lane_u8
 // CHECK: vmov 
 uint8x8_t test_vset_lane_u8(uint8_t a, uint8x8_t b) {
   return vset_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vset_lane_u16
+// CHECK-LABEL: test_vset_lane_u16
 // CHECK: vmov 
 uint16x4_t test_vset_lane_u16(uint16_t a, uint16x4_t b) {
   return vset_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vset_lane_u32
+// CHECK-LABEL: test_vset_lane_u32
 // CHECK: vmov 
 uint32x2_t test_vset_lane_u32(uint32_t a, uint32x2_t b) {
   return vset_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vset_lane_s8
+// CHECK-LABEL: test_vset_lane_s8
 // CHECK: vmov 
 int8x8_t test_vset_lane_s8(int8_t a, int8x8_t b) {
   return vset_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vset_lane_s16
+// CHECK-LABEL: test_vset_lane_s16
 // CHECK: vmov 
 int16x4_t test_vset_lane_s16(int16_t a, int16x4_t b) {
   return vset_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vset_lane_s32
+// CHECK-LABEL: test_vset_lane_s32
 // CHECK: vmov 
 int32x2_t test_vset_lane_s32(int32_t a, int32x2_t b) {
   return vset_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vset_lane_p8
+// CHECK-LABEL: test_vset_lane_p8
 // CHECK: vmov 
 poly8x8_t test_vset_lane_p8(poly8_t a, poly8x8_t b) {
   return vset_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vset_lane_p16
+// CHECK-LABEL: test_vset_lane_p16
 // CHECK: vmov 
 poly16x4_t test_vset_lane_p16(poly16_t a, poly16x4_t b) {
   return vset_lane_p16(a, b, 3);
 }
 
-// CHECK: test_vset_lane_f32
+// CHECK-LABEL: test_vset_lane_f32
 // CHECK: vmov 
 float32x2_t test_vset_lane_f32(float32_t a, float32x2_t b) {
   return vset_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vsetq_lane_u8
+// CHECK-LABEL: test_vsetq_lane_u8
 // CHECK: vmov 
 uint8x16_t test_vsetq_lane_u8(uint8_t a, uint8x16_t b) {
   return vsetq_lane_u8(a, b, 15);
 }
 
-// CHECK: test_vsetq_lane_u16
+// CHECK-LABEL: test_vsetq_lane_u16
 // CHECK: vmov 
 uint16x8_t test_vsetq_lane_u16(uint16_t a, uint16x8_t b) {
   return vsetq_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vsetq_lane_u32
+// CHECK-LABEL: test_vsetq_lane_u32
 // CHECK: vmov 
 uint32x4_t test_vsetq_lane_u32(uint32_t a, uint32x4_t b) {
   return vsetq_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vsetq_lane_s8
+// CHECK-LABEL: test_vsetq_lane_s8
 // CHECK: vmov 
 int8x16_t test_vsetq_lane_s8(int8_t a, int8x16_t b) {
   return vsetq_lane_s8(a, b, 15);
 }
 
-// CHECK: test_vsetq_lane_s16
+// CHECK-LABEL: test_vsetq_lane_s16
 // CHECK: vmov 
 int16x8_t test_vsetq_lane_s16(int16_t a, int16x8_t b) {
   return vsetq_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vsetq_lane_s32
+// CHECK-LABEL: test_vsetq_lane_s32
 // CHECK: vmov 
 int32x4_t test_vsetq_lane_s32(int32_t a, int32x4_t b) {
   return vsetq_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vsetq_lane_p8
+// CHECK-LABEL: test_vsetq_lane_p8
 // CHECK: vmov 
 poly8x16_t test_vsetq_lane_p8(poly8_t a, poly8x16_t b) {
   return vsetq_lane_p8(a, b, 15);
 }
 
-// CHECK: test_vsetq_lane_p16
+// CHECK-LABEL: test_vsetq_lane_p16
 // CHECK: vmov 
 poly16x8_t test_vsetq_lane_p16(poly16_t a, poly16x8_t b) {
   return vsetq_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vsetq_lane_f32
+// CHECK-LABEL: test_vsetq_lane_f32
 // CHECK: vmov 
 float32x4_t test_vsetq_lane_f32(float32_t a, float32x4_t b) {
   return vsetq_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vset_lane_s64
+// CHECK-LABEL: test_vset_lane_s64
 // CHECK: vmov 
 int64x1_t test_vset_lane_s64(int64_t a, int64x1_t b) {
   return vset_lane_s64(a, b, 0);
 }
 
-// CHECK: test_vset_lane_u64
+// CHECK-LABEL: test_vset_lane_u64
 // CHECK: vmov 
 uint64x1_t test_vset_lane_u64(uint64_t a, uint64x1_t b) {
   return vset_lane_u64(a, b, 0);
 }
 
-// CHECK: test_vsetq_lane_s64
+// CHECK-LABEL: test_vsetq_lane_s64
 // CHECK: vmov 
 int64x2_t test_vsetq_lane_s64(int64_t a, int64x2_t b) {
   return vsetq_lane_s64(a, b, 1);
 }
 
-// CHECK: test_vsetq_lane_u64
+// CHECK-LABEL: test_vsetq_lane_u64
 // CHECK: vmov 
 uint64x2_t test_vsetq_lane_u64(uint64_t a, uint64x2_t b) {
   return vsetq_lane_u64(a, b, 1);
 }
 
 
-// CHECK: test_vshl_s8
+// CHECK-LABEL: test_vshl_s8
 // CHECK: vshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vshl_s8(int8x8_t a, int8x8_t b) {
   return vshl_s8(a, b);
 }
 
-// CHECK: test_vshl_s16
+// CHECK-LABEL: test_vshl_s16
 // CHECK: vshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vshl_s16(int16x4_t a, int16x4_t b) {
   return vshl_s16(a, b);
 }
 
-// CHECK: test_vshl_s32
+// CHECK-LABEL: test_vshl_s32
 // CHECK: vshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vshl_s32(int32x2_t a, int32x2_t b) {
   return vshl_s32(a, b);
 }
 
-// CHECK: test_vshl_s64
+// CHECK-LABEL: test_vshl_s64
 // CHECK: vshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vshl_s64(int64x1_t a, int64x1_t b) {
   return vshl_s64(a, b);
 }
 
-// CHECK: test_vshl_u8
+// CHECK-LABEL: test_vshl_u8
 // CHECK: vshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vshl_u8(uint8x8_t a, int8x8_t b) {
   return vshl_u8(a, b);
 }
 
-// CHECK: test_vshl_u16
+// CHECK-LABEL: test_vshl_u16
 // CHECK: vshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vshl_u16(uint16x4_t a, int16x4_t b) {
   return vshl_u16(a, b);
 }
 
-// CHECK: test_vshl_u32
+// CHECK-LABEL: test_vshl_u32
 // CHECK: vshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vshl_u32(uint32x2_t a, int32x2_t b) {
   return vshl_u32(a, b);
 }
 
-// CHECK: test_vshl_u64
+// CHECK-LABEL: test_vshl_u64
 // CHECK: vshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vshl_u64(uint64x1_t a, int64x1_t b) {
   return vshl_u64(a, b);
 }
 
-// CHECK: test_vshlq_s8
+// CHECK-LABEL: test_vshlq_s8
 // CHECK: vshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vshlq_s8(int8x16_t a, int8x16_t b) {
   return vshlq_s8(a, b);
 }
 
-// CHECK: test_vshlq_s16
+// CHECK-LABEL: test_vshlq_s16
 // CHECK: vshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vshlq_s16(int16x8_t a, int16x8_t b) {
   return vshlq_s16(a, b);
 }
 
-// CHECK: test_vshlq_s32
+// CHECK-LABEL: test_vshlq_s32
 // CHECK: vshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vshlq_s32(int32x4_t a, int32x4_t b) {
   return vshlq_s32(a, b);
 }
 
-// CHECK: test_vshlq_s64
+// CHECK-LABEL: test_vshlq_s64
 // CHECK: vshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vshlq_s64(int64x2_t a, int64x2_t b) {
   return vshlq_s64(a, b);
 }
 
-// CHECK: test_vshlq_u8
+// CHECK-LABEL: test_vshlq_u8
 // CHECK: vshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vshlq_u8(uint8x16_t a, int8x16_t b) {
   return vshlq_u8(a, b);
 }
 
-// CHECK: test_vshlq_u16
+// CHECK-LABEL: test_vshlq_u16
 // CHECK: vshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vshlq_u16(uint16x8_t a, int16x8_t b) {
   return vshlq_u16(a, b);
 }
 
-// CHECK: test_vshlq_u32
+// CHECK-LABEL: test_vshlq_u32
 // CHECK: vshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vshlq_u32(uint32x4_t a, int32x4_t b) {
   return vshlq_u32(a, b);
 }
 
-// CHECK: test_vshlq_u64
+// CHECK-LABEL: test_vshlq_u64
 // CHECK: vshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vshlq_u64(uint64x2_t a, int64x2_t b) {
   return vshlq_u64(a, b);
 }
 
 
-// CHECK: test_vshll_n_s8
+// CHECK-LABEL: test_vshll_n_s8
 // CHECK: vshll.s8 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vshll_n_s8(int8x8_t a) {
   return vshll_n_s8(a, 1);
 }
 
-// CHECK: test_vshll_n_s16
+// CHECK-LABEL: test_vshll_n_s16
 // CHECK: vshll.s16 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vshll_n_s16(int16x4_t a) {
   return vshll_n_s16(a, 1);
 }
 
-// CHECK: test_vshll_n_s32
+// CHECK-LABEL: test_vshll_n_s32
 // CHECK: vshll.s32 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vshll_n_s32(int32x2_t a) {
   return vshll_n_s32(a, 1);
 }
 
-// CHECK: test_vshll_n_u8
+// CHECK-LABEL: test_vshll_n_u8
 // CHECK: vshll.u8 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vshll_n_u8(uint8x8_t a) {
   return vshll_n_u8(a, 1);
 }
 
-// CHECK: test_vshll_n_u16
+// CHECK-LABEL: test_vshll_n_u16
 // CHECK: vshll.u16 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vshll_n_u16(uint16x4_t a) {
   return vshll_n_u16(a, 1);
 }
 
-// CHECK: test_vshll_n_u32
+// CHECK-LABEL: test_vshll_n_u32
 // CHECK: vshll.u32 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vshll_n_u32(uint32x2_t a) {
   return vshll_n_u32(a, 1);
 }
 
 
-// CHECK: test_vshl_n_s8
+// CHECK-LABEL: test_vshl_n_s8
 // CHECK: vshl.i8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vshl_n_s8(int8x8_t a) {
   return vshl_n_s8(a, 1);
 }
 
-// CHECK: test_vshl_n_s16
+// CHECK-LABEL: test_vshl_n_s16
 // CHECK: vshl.i16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vshl_n_s16(int16x4_t a) {
   return vshl_n_s16(a, 1);
 }
 
-// CHECK: test_vshl_n_s32
+// CHECK-LABEL: test_vshl_n_s32
 // CHECK: vshl.i32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vshl_n_s32(int32x2_t a) {
   return vshl_n_s32(a, 1);
 }
 
-// CHECK: test_vshl_n_s64
+// CHECK-LABEL: test_vshl_n_s64
 // CHECK: vshl.i64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vshl_n_s64(int64x1_t a) {
   return vshl_n_s64(a, 1);
 }
 
-// CHECK: test_vshl_n_u8
+// CHECK-LABEL: test_vshl_n_u8
 // CHECK: vshl.i8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vshl_n_u8(uint8x8_t a) {
   return vshl_n_u8(a, 1);
 }
 
-// CHECK: test_vshl_n_u16
+// CHECK-LABEL: test_vshl_n_u16
 // CHECK: vshl.i16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vshl_n_u16(uint16x4_t a) {
   return vshl_n_u16(a, 1);
 }
 
-// CHECK: test_vshl_n_u32
+// CHECK-LABEL: test_vshl_n_u32
 // CHECK: vshl.i32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vshl_n_u32(uint32x2_t a) {
   return vshl_n_u32(a, 1);
 }
 
-// CHECK: test_vshl_n_u64
+// CHECK-LABEL: test_vshl_n_u64
 // CHECK: vshl.i64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vshl_n_u64(uint64x1_t a) {
   return vshl_n_u64(a, 1);
 }
 
-// CHECK: test_vshlq_n_s8
+// CHECK-LABEL: test_vshlq_n_s8
 // CHECK: vshl.i8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vshlq_n_s8(int8x16_t a) {
   return vshlq_n_s8(a, 1);
 }
 
-// CHECK: test_vshlq_n_s16
+// CHECK-LABEL: test_vshlq_n_s16
 // CHECK: vshl.i16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vshlq_n_s16(int16x8_t a) {
   return vshlq_n_s16(a, 1);
 }
 
-// CHECK: test_vshlq_n_s32
+// CHECK-LABEL: test_vshlq_n_s32
 // CHECK: vshl.i32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vshlq_n_s32(int32x4_t a) {
   return vshlq_n_s32(a, 1);
 }
 
-// CHECK: test_vshlq_n_s64
+// CHECK-LABEL: test_vshlq_n_s64
 // CHECK: vshl.i64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vshlq_n_s64(int64x2_t a) {
   return vshlq_n_s64(a, 1);
 }
 
-// CHECK: test_vshlq_n_u8
+// CHECK-LABEL: test_vshlq_n_u8
 // CHECK: vshl.i8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vshlq_n_u8(uint8x16_t a) {
   return vshlq_n_u8(a, 1);
 }
 
-// CHECK: test_vshlq_n_u16
+// CHECK-LABEL: test_vshlq_n_u16
 // CHECK: vshl.i16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vshlq_n_u16(uint16x8_t a) {
   return vshlq_n_u16(a, 1);
 }
 
-// CHECK: test_vshlq_n_u32
+// CHECK-LABEL: test_vshlq_n_u32
 // CHECK: vshl.i32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vshlq_n_u32(uint32x4_t a) {
   return vshlq_n_u32(a, 1);
 }
 
-// CHECK: test_vshlq_n_u64
+// CHECK-LABEL: test_vshlq_n_u64
 // CHECK: vshl.i64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vshlq_n_u64(uint64x2_t a) {
   return vshlq_n_u64(a, 1);
 }
 
 
-// CHECK: test_vshrn_n_s16
+// CHECK-LABEL: test_vshrn_n_s16
 // CHECK: vshrn.i16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vshrn_n_s16(int16x8_t a) {
   return vshrn_n_s16(a, 1);
 }
 
-// CHECK: test_vshrn_n_s32
+// CHECK-LABEL: test_vshrn_n_s32
 // CHECK: vshrn.i32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vshrn_n_s32(int32x4_t a) {
   return vshrn_n_s32(a, 1);
 }
 
-// CHECK: test_vshrn_n_s64
+// CHECK-LABEL: test_vshrn_n_s64
 // CHECK: vshrn.i64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vshrn_n_s64(int64x2_t a) {
   return vshrn_n_s64(a, 1);
 }
 
-// CHECK: test_vshrn_n_u16
+// CHECK-LABEL: test_vshrn_n_u16
 // CHECK: vshrn.i16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vshrn_n_u16(uint16x8_t a) {
   return vshrn_n_u16(a, 1);
 }
 
-// CHECK: test_vshrn_n_u32
+// CHECK-LABEL: test_vshrn_n_u32
 // CHECK: vshrn.i32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vshrn_n_u32(uint32x4_t a) {
   return vshrn_n_u32(a, 1);
 }
 
-// CHECK: test_vshrn_n_u64
+// CHECK-LABEL: test_vshrn_n_u64
 // CHECK: vshrn.i64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vshrn_n_u64(uint64x2_t a) {
   return vshrn_n_u64(a, 1);
 }
 
 
-// CHECK: test_vshr_n_s8
+// CHECK-LABEL: test_vshr_n_s8
 // CHECK: vshr.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vshr_n_s8(int8x8_t a) {
   return vshr_n_s8(a, 1);
 }
 
-// CHECK: test_vshr_n_s16
+// CHECK-LABEL: test_vshr_n_s16
 // CHECK: vshr.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vshr_n_s16(int16x4_t a) {
   return vshr_n_s16(a, 1);
 }
 
-// CHECK: test_vshr_n_s32
+// CHECK-LABEL: test_vshr_n_s32
 // CHECK: vshr.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vshr_n_s32(int32x2_t a) {
   return vshr_n_s32(a, 1);
 }
 
-// CHECK: test_vshr_n_s64
+// CHECK-LABEL: test_vshr_n_s64
 // CHECK: vshr.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vshr_n_s64(int64x1_t a) {
   return vshr_n_s64(a, 1);
 }
 
-// CHECK: test_vshr_n_u8
+// CHECK-LABEL: test_vshr_n_u8
 // CHECK: vshr.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vshr_n_u8(uint8x8_t a) {
   return vshr_n_u8(a, 1);
 }
 
-// CHECK: test_vshr_n_u16
+// CHECK-LABEL: test_vshr_n_u16
 // CHECK: vshr.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vshr_n_u16(uint16x4_t a) {
   return vshr_n_u16(a, 1);
 }
 
-// CHECK: test_vshr_n_u32
+// CHECK-LABEL: test_vshr_n_u32
 // CHECK: vshr.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vshr_n_u32(uint32x2_t a) {
   return vshr_n_u32(a, 1);
 }
 
-// CHECK: test_vshr_n_u64
+// CHECK-LABEL: test_vshr_n_u64
 // CHECK: vshr.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vshr_n_u64(uint64x1_t a) {
   return vshr_n_u64(a, 1);
 }
 
-// CHECK: test_vshrq_n_s8
+// CHECK-LABEL: test_vshrq_n_s8
 // CHECK: vshr.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vshrq_n_s8(int8x16_t a) {
   return vshrq_n_s8(a, 1);
 }
 
-// CHECK: test_vshrq_n_s16
+// CHECK-LABEL: test_vshrq_n_s16
 // CHECK: vshr.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vshrq_n_s16(int16x8_t a) {
   return vshrq_n_s16(a, 1);
 }
 
-// CHECK: test_vshrq_n_s32
+// CHECK-LABEL: test_vshrq_n_s32
 // CHECK: vshr.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vshrq_n_s32(int32x4_t a) {
   return vshrq_n_s32(a, 1);
 }
 
-// CHECK: test_vshrq_n_s64
+// CHECK-LABEL: test_vshrq_n_s64
 // CHECK: vshr.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vshrq_n_s64(int64x2_t a) {
   return vshrq_n_s64(a, 1);
 }
 
-// CHECK: test_vshrq_n_u8
+// CHECK-LABEL: test_vshrq_n_u8
 // CHECK: vshr.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vshrq_n_u8(uint8x16_t a) {
   return vshrq_n_u8(a, 1);
 }
 
-// CHECK: test_vshrq_n_u16
+// CHECK-LABEL: test_vshrq_n_u16
 // CHECK: vshr.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vshrq_n_u16(uint16x8_t a) {
   return vshrq_n_u16(a, 1);
 }
 
-// CHECK: test_vshrq_n_u32
+// CHECK-LABEL: test_vshrq_n_u32
 // CHECK: vshr.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vshrq_n_u32(uint32x4_t a) {
   return vshrq_n_u32(a, 1);
 }
 
-// CHECK: test_vshrq_n_u64
+// CHECK-LABEL: test_vshrq_n_u64
 // CHECK: vshr.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vshrq_n_u64(uint64x2_t a) {
   return vshrq_n_u64(a, 1);
 }
 
 
-// CHECK: test_vsli_n_s8
+// CHECK-LABEL: test_vsli_n_s8
 // CHECK: vsli.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vsli_n_s8(int8x8_t a, int8x8_t b) {
   return vsli_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsli_n_s16
+// CHECK-LABEL: test_vsli_n_s16
 // CHECK: vsli.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vsli_n_s16(int16x4_t a, int16x4_t b) {
   return vsli_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsli_n_s32
+// CHECK-LABEL: test_vsli_n_s32
 // CHECK: vsli.32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vsli_n_s32(int32x2_t a, int32x2_t b) {
   return vsli_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsli_n_s64
+// CHECK-LABEL: test_vsli_n_s64
 // CHECK: vsli.64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vsli_n_s64(int64x1_t a, int64x1_t b) {
   return vsli_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsli_n_u8
+// CHECK-LABEL: test_vsli_n_u8
 // CHECK: vsli.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vsli_n_u8(uint8x8_t a, uint8x8_t b) {
   return vsli_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsli_n_u16
+// CHECK-LABEL: test_vsli_n_u16
 // CHECK: vsli.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vsli_n_u16(uint16x4_t a, uint16x4_t b) {
   return vsli_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsli_n_u32
+// CHECK-LABEL: test_vsli_n_u32
 // CHECK: vsli.32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vsli_n_u32(uint32x2_t a, uint32x2_t b) {
   return vsli_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsli_n_u64
+// CHECK-LABEL: test_vsli_n_u64
 // CHECK: vsli.64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vsli_n_u64(uint64x1_t a, uint64x1_t b) {
   return vsli_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsli_n_p8
+// CHECK-LABEL: test_vsli_n_p8
 // CHECK: vsli.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly8x8_t test_vsli_n_p8(poly8x8_t a, poly8x8_t b) {
   return vsli_n_p8(a, b, 1);
 }
 
-// CHECK: test_vsli_n_p16
+// CHECK-LABEL: test_vsli_n_p16
 // CHECK: vsli.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly16x4_t test_vsli_n_p16(poly16x4_t a, poly16x4_t b) {
   return vsli_n_p16(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_s8
+// CHECK-LABEL: test_vsliq_n_s8
 // CHECK: vsli.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vsliq_n_s8(int8x16_t a, int8x16_t b) {
   return vsliq_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_s16
+// CHECK-LABEL: test_vsliq_n_s16
 // CHECK: vsli.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vsliq_n_s16(int16x8_t a, int16x8_t b) {
   return vsliq_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_s32
+// CHECK-LABEL: test_vsliq_n_s32
 // CHECK: vsli.32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vsliq_n_s32(int32x4_t a, int32x4_t b) {
   return vsliq_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_s64
+// CHECK-LABEL: test_vsliq_n_s64
 // CHECK: vsli.64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vsliq_n_s64(int64x2_t a, int64x2_t b) {
   return vsliq_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_u8
+// CHECK-LABEL: test_vsliq_n_u8
 // CHECK: vsli.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vsliq_n_u8(uint8x16_t a, uint8x16_t b) {
   return vsliq_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_u16
+// CHECK-LABEL: test_vsliq_n_u16
 // CHECK: vsli.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vsliq_n_u16(uint16x8_t a, uint16x8_t b) {
   return vsliq_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_u32
+// CHECK-LABEL: test_vsliq_n_u32
 // CHECK: vsli.32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vsliq_n_u32(uint32x4_t a, uint32x4_t b) {
   return vsliq_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_u64
+// CHECK-LABEL: test_vsliq_n_u64
 // CHECK: vsli.64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vsliq_n_u64(uint64x2_t a, uint64x2_t b) {
   return vsliq_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_p8
+// CHECK-LABEL: test_vsliq_n_p8
 // CHECK: vsli.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly8x16_t test_vsliq_n_p8(poly8x16_t a, poly8x16_t b) {
   return vsliq_n_p8(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_p16
+// CHECK-LABEL: test_vsliq_n_p16
 // CHECK: vsli.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly16x8_t test_vsliq_n_p16(poly16x8_t a, poly16x8_t b) {
   return vsliq_n_p16(a, b, 1);
 }
 
 
-// CHECK: test_vsra_n_s8
+// CHECK-LABEL: test_vsra_n_s8
 // CHECK: vsra.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vsra_n_s8(int8x8_t a, int8x8_t b) {
   return vsra_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsra_n_s16
+// CHECK-LABEL: test_vsra_n_s16
 // CHECK: vsra.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vsra_n_s16(int16x4_t a, int16x4_t b) {
   return vsra_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsra_n_s32
+// CHECK-LABEL: test_vsra_n_s32
 // CHECK: vsra.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vsra_n_s32(int32x2_t a, int32x2_t b) {
   return vsra_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsra_n_s64
+// CHECK-LABEL: test_vsra_n_s64
 // CHECK: vsra.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vsra_n_s64(int64x1_t a, int64x1_t b) {
   return vsra_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsra_n_u8
+// CHECK-LABEL: test_vsra_n_u8
 // CHECK: vsra.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vsra_n_u8(uint8x8_t a, uint8x8_t b) {
   return vsra_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsra_n_u16
+// CHECK-LABEL: test_vsra_n_u16
 // CHECK: vsra.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vsra_n_u16(uint16x4_t a, uint16x4_t b) {
   return vsra_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsra_n_u32
+// CHECK-LABEL: test_vsra_n_u32
 // CHECK: vsra.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vsra_n_u32(uint32x2_t a, uint32x2_t b) {
   return vsra_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsra_n_u64
+// CHECK-LABEL: test_vsra_n_u64
 // CHECK: vsra.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vsra_n_u64(uint64x1_t a, uint64x1_t b) {
   return vsra_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_s8
+// CHECK-LABEL: test_vsraq_n_s8
 // CHECK: vsra.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vsraq_n_s8(int8x16_t a, int8x16_t b) {
   return vsraq_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_s16
+// CHECK-LABEL: test_vsraq_n_s16
 // CHECK: vsra.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vsraq_n_s16(int16x8_t a, int16x8_t b) {
   return vsraq_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_s32
+// CHECK-LABEL: test_vsraq_n_s32
 // CHECK: vsra.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vsraq_n_s32(int32x4_t a, int32x4_t b) {
   return vsraq_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_s64
+// CHECK-LABEL: test_vsraq_n_s64
 // CHECK: vsra.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vsraq_n_s64(int64x2_t a, int64x2_t b) {
   return vsraq_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_u8
+// CHECK-LABEL: test_vsraq_n_u8
 // CHECK: vsra.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vsraq_n_u8(uint8x16_t a, uint8x16_t b) {
   return vsraq_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_u16
+// CHECK-LABEL: test_vsraq_n_u16
 // CHECK: vsra.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vsraq_n_u16(uint16x8_t a, uint16x8_t b) {
   return vsraq_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_u32
+// CHECK-LABEL: test_vsraq_n_u32
 // CHECK: vsra.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vsraq_n_u32(uint32x4_t a, uint32x4_t b) {
   return vsraq_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_u64
+// CHECK-LABEL: test_vsraq_n_u64
 // CHECK: vsra.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vsraq_n_u64(uint64x2_t a, uint64x2_t b) {
   return vsraq_n_u64(a, b, 1);
 }
 
 
-// CHECK: test_vsri_n_s8
+// CHECK-LABEL: test_vsri_n_s8
 // CHECK: vsri.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vsri_n_s8(int8x8_t a, int8x8_t b) {
   return vsri_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsri_n_s16
+// CHECK-LABEL: test_vsri_n_s16
 // CHECK: vsri.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vsri_n_s16(int16x4_t a, int16x4_t b) {
   return vsri_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsri_n_s32
+// CHECK-LABEL: test_vsri_n_s32
 // CHECK: vsri.32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vsri_n_s32(int32x2_t a, int32x2_t b) {
   return vsri_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsri_n_s64
+// CHECK-LABEL: test_vsri_n_s64
 // CHECK: vsri.64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vsri_n_s64(int64x1_t a, int64x1_t b) {
   return vsri_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsri_n_u8
+// CHECK-LABEL: test_vsri_n_u8
 // CHECK: vsri.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vsri_n_u8(uint8x8_t a, uint8x8_t b) {
   return vsri_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsri_n_u16
+// CHECK-LABEL: test_vsri_n_u16
 // CHECK: vsri.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vsri_n_u16(uint16x4_t a, uint16x4_t b) {
   return vsri_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsri_n_u32
+// CHECK-LABEL: test_vsri_n_u32
 // CHECK: vsri.32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vsri_n_u32(uint32x2_t a, uint32x2_t b) {
   return vsri_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsri_n_u64
+// CHECK-LABEL: test_vsri_n_u64
 // CHECK: vsri.64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vsri_n_u64(uint64x1_t a, uint64x1_t b) {
   return vsri_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsri_n_p8
+// CHECK-LABEL: test_vsri_n_p8
 // CHECK: vsri.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly8x8_t test_vsri_n_p8(poly8x8_t a, poly8x8_t b) {
   return vsri_n_p8(a, b, 1);
 }
 
-// CHECK: test_vsri_n_p16
+// CHECK-LABEL: test_vsri_n_p16
 // CHECK: vsri.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly16x4_t test_vsri_n_p16(poly16x4_t a, poly16x4_t b) {
   return vsri_n_p16(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_s8
+// CHECK-LABEL: test_vsriq_n_s8
 // CHECK: vsri.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vsriq_n_s8(int8x16_t a, int8x16_t b) {
   return vsriq_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_s16
+// CHECK-LABEL: test_vsriq_n_s16
 // CHECK: vsri.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vsriq_n_s16(int16x8_t a, int16x8_t b) {
   return vsriq_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_s32
+// CHECK-LABEL: test_vsriq_n_s32
 // CHECK: vsri.32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vsriq_n_s32(int32x4_t a, int32x4_t b) {
   return vsriq_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_s64
+// CHECK-LABEL: test_vsriq_n_s64
 // CHECK: vsri.64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vsriq_n_s64(int64x2_t a, int64x2_t b) {
   return vsriq_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_u8
+// CHECK-LABEL: test_vsriq_n_u8
 // CHECK: vsri.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vsriq_n_u8(uint8x16_t a, uint8x16_t b) {
   return vsriq_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_u16
+// CHECK-LABEL: test_vsriq_n_u16
 // CHECK: vsri.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vsriq_n_u16(uint16x8_t a, uint16x8_t b) {
   return vsriq_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_u32
+// CHECK-LABEL: test_vsriq_n_u32
 // CHECK: vsri.32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vsriq_n_u32(uint32x4_t a, uint32x4_t b) {
   return vsriq_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_u64
+// CHECK-LABEL: test_vsriq_n_u64
 // CHECK: vsri.64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vsriq_n_u64(uint64x2_t a, uint64x2_t b) {
   return vsriq_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_p8
+// CHECK-LABEL: test_vsriq_n_p8
 // CHECK: vsri.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly8x16_t test_vsriq_n_p8(poly8x16_t a, poly8x16_t b) {
   return vsriq_n_p8(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_p16
+// CHECK-LABEL: test_vsriq_n_p16
 // CHECK: vsri.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly16x8_t test_vsriq_n_p16(poly16x8_t a, poly16x8_t b) {
   return vsriq_n_p16(a, b, 1);
 }
 
 
-// CHECK: test_vst1q_u8
+// CHECK-LABEL: test_vst1q_u8
 // CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_u8(uint8_t * a, uint8x16_t b) {
   vst1q_u8(a, b);
 }
 
-// CHECK: test_vst1q_u16
+// CHECK-LABEL: test_vst1q_u16
 // CHECK: vst1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_u16(uint16_t * a, uint16x8_t b) {
   vst1q_u16(a, b);
 }
 
-// CHECK: test_vst1q_u32
+// CHECK-LABEL: test_vst1q_u32
 // CHECK: vst1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_u32(uint32_t * a, uint32x4_t b) {
   vst1q_u32(a, b);
 }
 
-// CHECK: test_vst1q_u64
-// CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vst1q_u64
+// CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 void test_vst1q_u64(uint64_t * a, uint64x2_t b) {
   vst1q_u64(a, b);
 }
 
-// CHECK: test_vst1q_s8
+// CHECK-LABEL: test_vst1q_s8
 // CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_s8(int8_t * a, int8x16_t b) {
   vst1q_s8(a, b);
 }
 
-// CHECK: test_vst1q_s16
+// CHECK-LABEL: test_vst1q_s16
 // CHECK: vst1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_s16(int16_t * a, int16x8_t b) {
   vst1q_s16(a, b);
 }
 
-// CHECK: test_vst1q_s32
+// CHECK-LABEL: test_vst1q_s32
 // CHECK: vst1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_s32(int32_t * a, int32x4_t b) {
   vst1q_s32(a, b);
 }
 
-// CHECK: test_vst1q_s64
-// CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vst1q_s64
+// CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 void test_vst1q_s64(int64_t * a, int64x2_t b) {
   vst1q_s64(a, b);
 }
 
-// CHECK: test_vst1q_f16
+// CHECK-LABEL: test_vst1q_f16
 // CHECK: vst1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_f16(float16_t * a, float16x8_t b) {
   vst1q_f16(a, b);
 }
 
-// CHECK: test_vst1q_f32
+// CHECK-LABEL: test_vst1q_f32
 // CHECK: vst1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_f32(float32_t * a, float32x4_t b) {
   vst1q_f32(a, b);
 }
 
-// CHECK: test_vst1q_p8
+// CHECK-LABEL: test_vst1q_p8
 // CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_p8(poly8_t * a, poly8x16_t b) {
   vst1q_p8(a, b);
 }
 
-// CHECK: test_vst1q_p16
+// CHECK-LABEL: test_vst1q_p16
 // CHECK: vst1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_p16(poly16_t * a, poly16x8_t b) {
   vst1q_p16(a, b);
 }
 
-// CHECK: test_vst1_u8
+// CHECK-LABEL: test_vst1_u8
 // CHECK: vst1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_u8(uint8_t * a, uint8x8_t b) {
   vst1_u8(a, b);
 }
 
-// CHECK: test_vst1_u16
+// CHECK-LABEL: test_vst1_u16
 // CHECK: vst1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_u16(uint16_t * a, uint16x4_t b) {
   vst1_u16(a, b);
 }
 
-// CHECK: test_vst1_u32
+// CHECK-LABEL: test_vst1_u32
 // CHECK: vst1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_u32(uint32_t * a, uint32x2_t b) {
   vst1_u32(a, b);
 }
 
-// CHECK: test_vst1_u64
-// CHECK: vst1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vst1_u64
+// CHECK: vst1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 void test_vst1_u64(uint64_t * a, uint64x1_t b) {
   vst1_u64(a, b);
 }
 
-// CHECK: test_vst1_s8
+// CHECK-LABEL: test_vst1_s8
 // CHECK: vst1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_s8(int8_t * a, int8x8_t b) {
   vst1_s8(a, b);
 }
 
-// CHECK: test_vst1_s16
+// CHECK-LABEL: test_vst1_s16
 // CHECK: vst1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_s16(int16_t * a, int16x4_t b) {
   vst1_s16(a, b);
 }
 
-// CHECK: test_vst1_s32
+// CHECK-LABEL: test_vst1_s32
 // CHECK: vst1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_s32(int32_t * a, int32x2_t b) {
   vst1_s32(a, b);
 }
 
-// CHECK: test_vst1_s64
-// CHECK: vst1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vst1_s64
+// CHECK: vst1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 void test_vst1_s64(int64_t * a, int64x1_t b) {
   vst1_s64(a, b);
 }
 
-// CHECK: test_vst1_f16
+// CHECK-LABEL: test_vst1_f16
 // CHECK: vst1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_f16(float16_t * a, float16x4_t b) {
   vst1_f16(a, b);
 }
 
-// CHECK: test_vst1_f32
+// CHECK-LABEL: test_vst1_f32
 // CHECK: vst1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_f32(float32_t * a, float32x2_t b) {
   vst1_f32(a, b);
 }
 
-// CHECK: test_vst1_p8
+// CHECK-LABEL: test_vst1_p8
 // CHECK: vst1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_p8(poly8_t * a, poly8x8_t b) {
   vst1_p8(a, b);
 }
 
-// CHECK: test_vst1_p16
+// CHECK-LABEL: test_vst1_p16
 // CHECK: vst1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_p16(poly16_t * a, poly16x4_t b) {
   vst1_p16(a, b);
 }
 
 
-// CHECK: test_vst1q_lane_u8
+// CHECK-LABEL: test_vst1q_lane_u8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1q_lane_u8(uint8_t * a, uint8x16_t b) {
   vst1q_lane_u8(a, b, 15);
 }
 
-// CHECK: test_vst1q_lane_u16
+// CHECK-LABEL: test_vst1q_lane_u16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1q_lane_u16(uint16_t * a, uint16x8_t b) {
   vst1q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vst1q_lane_u32
+// CHECK-LABEL: test_vst1q_lane_u32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1q_lane_u32(uint32_t * a, uint32x4_t b) {
   vst1q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vst1q_lane_u64
+// CHECK-LABEL: test_vst1q_lane_u64
 // CHECK: {{str|vstr|vmov}}
 void test_vst1q_lane_u64(uint64_t * a, uint64x2_t b) {
   vst1q_lane_u64(a, b, 1);
 }
 
-// CHECK: test_vst1q_lane_s8
+// CHECK-LABEL: test_vst1q_lane_s8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1q_lane_s8(int8_t * a, int8x16_t b) {
   vst1q_lane_s8(a, b, 15);
 }
 
-// CHECK: test_vst1q_lane_s16
+// CHECK-LABEL: test_vst1q_lane_s16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1q_lane_s16(int16_t * a, int16x8_t b) {
   vst1q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vst1q_lane_s32
+// CHECK-LABEL: test_vst1q_lane_s32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1q_lane_s32(int32_t * a, int32x4_t b) {
   vst1q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vst1q_lane_s64
+// CHECK-LABEL: test_vst1q_lane_s64
 // CHECK: {{str|vstr|vmov}}
 void test_vst1q_lane_s64(int64_t * a, int64x2_t b) {
   vst1q_lane_s64(a, b, 1);
 }
 
-// CHECK: test_vst1q_lane_f16
+// CHECK-LABEL: test_vst1q_lane_f16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1q_lane_f16(float16_t * a, float16x8_t b) {
   vst1q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vst1q_lane_f32
+// CHECK-LABEL: test_vst1q_lane_f32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1q_lane_f32(float32_t * a, float32x4_t b) {
   vst1q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vst1q_lane_p8
+// CHECK-LABEL: test_vst1q_lane_p8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1q_lane_p8(poly8_t * a, poly8x16_t b) {
   vst1q_lane_p8(a, b, 15);
 }
 
-// CHECK: test_vst1q_lane_p16
+// CHECK-LABEL: test_vst1q_lane_p16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1q_lane_p16(poly16_t * a, poly16x8_t b) {
   vst1q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vst1_lane_u8
+// CHECK-LABEL: test_vst1_lane_u8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1_lane_u8(uint8_t * a, uint8x8_t b) {
   vst1_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vst1_lane_u16
+// CHECK-LABEL: test_vst1_lane_u16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1_lane_u16(uint16_t * a, uint16x4_t b) {
   vst1_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vst1_lane_u32
+// CHECK-LABEL: test_vst1_lane_u32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1_lane_u32(uint32_t * a, uint32x2_t b) {
   vst1_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vst1_lane_u64
+// CHECK-LABEL: test_vst1_lane_u64
 // CHECK: {{str|vstr|vmov}}
 void test_vst1_lane_u64(uint64_t * a, uint64x1_t b) {
   vst1_lane_u64(a, b, 0);
 }
 
-// CHECK: test_vst1_lane_s8
+// CHECK-LABEL: test_vst1_lane_s8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1_lane_s8(int8_t * a, int8x8_t b) {
   vst1_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vst1_lane_s16
+// CHECK-LABEL: test_vst1_lane_s16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1_lane_s16(int16_t * a, int16x4_t b) {
   vst1_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vst1_lane_s32
+// CHECK-LABEL: test_vst1_lane_s32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1_lane_s32(int32_t * a, int32x2_t b) {
   vst1_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vst1_lane_s64
+// CHECK-LABEL: test_vst1_lane_s64
 // CHECK: {{str|vstr|vmov}}
 void test_vst1_lane_s64(int64_t * a, int64x1_t b) {
   vst1_lane_s64(a, b, 0);
 }
 
-// CHECK: test_vst1_lane_f16
+// CHECK-LABEL: test_vst1_lane_f16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1_lane_f16(float16_t * a, float16x4_t b) {
   vst1_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vst1_lane_f32
+// CHECK-LABEL: test_vst1_lane_f32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1_lane_f32(float32_t * a, float32x2_t b) {
   vst1_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vst1_lane_p8
+// CHECK-LABEL: test_vst1_lane_p8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1_lane_p8(poly8_t * a, poly8x8_t b) {
   vst1_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vst1_lane_p16
+// CHECK-LABEL: test_vst1_lane_p16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1_lane_p16(poly16_t * a, poly16x4_t b) {
   vst1_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vst2q_u8
+// CHECK-LABEL: test_vst2q_u8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_u8(uint8_t * a, uint8x16x2_t b) {
   vst2q_u8(a, b);
 }
 
-// CHECK: test_vst2q_u16
+// CHECK-LABEL: test_vst2q_u16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_u16(uint16_t * a, uint16x8x2_t b) {
   vst2q_u16(a, b);
 }
 
-// CHECK: test_vst2q_u32
+// CHECK-LABEL: test_vst2q_u32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_u32(uint32_t * a, uint32x4x2_t b) {
   vst2q_u32(a, b);
 }
 
-// CHECK: test_vst2q_s8
+// CHECK-LABEL: test_vst2q_s8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_s8(int8_t * a, int8x16x2_t b) {
   vst2q_s8(a, b);
 }
 
-// CHECK: test_vst2q_s16
+// CHECK-LABEL: test_vst2q_s16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_s16(int16_t * a, int16x8x2_t b) {
   vst2q_s16(a, b);
 }
 
-// CHECK: test_vst2q_s32
+// CHECK-LABEL: test_vst2q_s32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_s32(int32_t * a, int32x4x2_t b) {
   vst2q_s32(a, b);
 }
 
-// CHECK: test_vst2q_f16
+// CHECK-LABEL: test_vst2q_f16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_f16(float16_t * a, float16x8x2_t b) {
   vst2q_f16(a, b);
 }
 
-// CHECK: test_vst2q_f32
+// CHECK-LABEL: test_vst2q_f32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_f32(float32_t * a, float32x4x2_t b) {
   vst2q_f32(a, b);
 }
 
-// CHECK: test_vst2q_p8
+// CHECK-LABEL: test_vst2q_p8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_p8(poly8_t * a, poly8x16x2_t b) {
   vst2q_p8(a, b);
 }
 
-// CHECK: test_vst2q_p16
+// CHECK-LABEL: test_vst2q_p16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_p16(poly16_t * a, poly16x8x2_t b) {
   vst2q_p16(a, b);
 }
 
-// CHECK: test_vst2_u8
+// CHECK-LABEL: test_vst2_u8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_u8(uint8_t * a, uint8x8x2_t b) {
   vst2_u8(a, b);
 }
 
-// CHECK: test_vst2_u16
+// CHECK-LABEL: test_vst2_u16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_u16(uint16_t * a, uint16x4x2_t b) {
   vst2_u16(a, b);
 }
 
-// CHECK: test_vst2_u32
+// CHECK-LABEL: test_vst2_u32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_u32(uint32_t * a, uint32x2x2_t b) {
   vst2_u32(a, b);
 }
 
-// CHECK: test_vst2_u64
+// CHECK-LABEL: test_vst2_u64
 // CHECK: vst1.64
 void test_vst2_u64(uint64_t * a, uint64x1x2_t b) {
   vst2_u64(a, b);
 }
 
-// CHECK: test_vst2_s8
+// CHECK-LABEL: test_vst2_s8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_s8(int8_t * a, int8x8x2_t b) {
   vst2_s8(a, b);
 }
 
-// CHECK: test_vst2_s16
+// CHECK-LABEL: test_vst2_s16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_s16(int16_t * a, int16x4x2_t b) {
   vst2_s16(a, b);
 }
 
-// CHECK: test_vst2_s32
+// CHECK-LABEL: test_vst2_s32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_s32(int32_t * a, int32x2x2_t b) {
   vst2_s32(a, b);
 }
 
-// CHECK: test_vst2_s64
+// CHECK-LABEL: test_vst2_s64
 // CHECK: vst1.64
 void test_vst2_s64(int64_t * a, int64x1x2_t b) {
   vst2_s64(a, b);
 }
 
-// CHECK: test_vst2_f16
+// CHECK-LABEL: test_vst2_f16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_f16(float16_t * a, float16x4x2_t b) {
   vst2_f16(a, b);
 }
 
-// CHECK: test_vst2_f32
+// CHECK-LABEL: test_vst2_f32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_f32(float32_t * a, float32x2x2_t b) {
   vst2_f32(a, b);
 }
 
-// CHECK: test_vst2_p8
+// CHECK-LABEL: test_vst2_p8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_p8(poly8_t * a, poly8x8x2_t b) {
   vst2_p8(a, b);
 }
 
-// CHECK: test_vst2_p16
+// CHECK-LABEL: test_vst2_p16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_p16(poly16_t * a, poly16x4x2_t b) {
   vst2_p16(a, b);
 }
 
 
-// CHECK: test_vst2q_lane_u16
+// CHECK-LABEL: test_vst2q_lane_u16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_u16(uint16_t * a, uint16x8x2_t b) {
   vst2q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vst2q_lane_u32
+// CHECK-LABEL: test_vst2q_lane_u32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_u32(uint32_t * a, uint32x4x2_t b) {
   vst2q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vst2q_lane_s16
+// CHECK-LABEL: test_vst2q_lane_s16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_s16(int16_t * a, int16x8x2_t b) {
   vst2q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vst2q_lane_s32
+// CHECK-LABEL: test_vst2q_lane_s32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_s32(int32_t * a, int32x4x2_t b) {
   vst2q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vst2q_lane_f16
+// CHECK-LABEL: test_vst2q_lane_f16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_f16(float16_t * a, float16x8x2_t b) {
   vst2q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vst2q_lane_f32
+// CHECK-LABEL: test_vst2q_lane_f32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_f32(float32_t * a, float32x4x2_t b) {
   vst2q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vst2q_lane_p16
+// CHECK-LABEL: test_vst2q_lane_p16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_p16(poly16_t * a, poly16x8x2_t b) {
   vst2q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vst2_lane_u8
+// CHECK-LABEL: test_vst2_lane_u8
 // CHECK: vst2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_u8(uint8_t * a, uint8x8x2_t b) {
   vst2_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vst2_lane_u16
+// CHECK-LABEL: test_vst2_lane_u16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_u16(uint16_t * a, uint16x4x2_t b) {
   vst2_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vst2_lane_u32
+// CHECK-LABEL: test_vst2_lane_u32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_u32(uint32_t * a, uint32x2x2_t b) {
   vst2_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vst2_lane_s8
+// CHECK-LABEL: test_vst2_lane_s8
 // CHECK: vst2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_s8(int8_t * a, int8x8x2_t b) {
   vst2_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vst2_lane_s16
+// CHECK-LABEL: test_vst2_lane_s16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_s16(int16_t * a, int16x4x2_t b) {
   vst2_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vst2_lane_s32
+// CHECK-LABEL: test_vst2_lane_s32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_s32(int32_t * a, int32x2x2_t b) {
   vst2_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vst2_lane_f16
+// CHECK-LABEL: test_vst2_lane_f16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_f16(float16_t * a, float16x4x2_t b) {
   vst2_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vst2_lane_f32
+// CHECK-LABEL: test_vst2_lane_f32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_f32(float32_t * a, float32x2x2_t b) {
   vst2_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vst2_lane_p8
+// CHECK-LABEL: test_vst2_lane_p8
 // CHECK: vst2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_p8(poly8_t * a, poly8x8x2_t b) {
   vst2_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vst2_lane_p16
+// CHECK-LABEL: test_vst2_lane_p16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_p16(poly16_t * a, poly16x4x2_t b) {
   vst2_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vst3q_u8
+// CHECK-LABEL: test_vst3q_u8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_u8(uint8_t * a, uint8x16x3_t b) {
   vst3q_u8(a, b);
 }
 
-// CHECK: test_vst3q_u16
+// CHECK-LABEL: test_vst3q_u16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_u16(uint16_t * a, uint16x8x3_t b) {
   vst3q_u16(a, b);
 }
 
-// CHECK: test_vst3q_u32
+// CHECK-LABEL: test_vst3q_u32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_u32(uint32_t * a, uint32x4x3_t b) {
   vst3q_u32(a, b);
 }
 
-// CHECK: test_vst3q_s8
+// CHECK-LABEL: test_vst3q_s8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_s8(int8_t * a, int8x16x3_t b) {
   vst3q_s8(a, b);
 }
 
-// CHECK: test_vst3q_s16
+// CHECK-LABEL: test_vst3q_s16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_s16(int16_t * a, int16x8x3_t b) {
   vst3q_s16(a, b);
 }
 
-// CHECK: test_vst3q_s32
+// CHECK-LABEL: test_vst3q_s32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_s32(int32_t * a, int32x4x3_t b) {
   vst3q_s32(a, b);
 }
 
-// CHECK: test_vst3q_f16
+// CHECK-LABEL: test_vst3q_f16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_f16(float16_t * a, float16x8x3_t b) {
   vst3q_f16(a, b);
 }
 
-// CHECK: test_vst3q_f32
+// CHECK-LABEL: test_vst3q_f32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_f32(float32_t * a, float32x4x3_t b) {
   vst3q_f32(a, b);
 }
 
-// CHECK: test_vst3q_p8
+// CHECK-LABEL: test_vst3q_p8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_p8(poly8_t * a, poly8x16x3_t b) {
   vst3q_p8(a, b);
 }
 
-// CHECK: test_vst3q_p16
+// CHECK-LABEL: test_vst3q_p16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_p16(poly16_t * a, poly16x8x3_t b) {
   vst3q_p16(a, b);
 }
 
-// CHECK: test_vst3_u8
+// CHECK-LABEL: test_vst3_u8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_u8(uint8_t * a, uint8x8x3_t b) {
   vst3_u8(a, b);
 }
 
-// CHECK: test_vst3_u16
+// CHECK-LABEL: test_vst3_u16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_u16(uint16_t * a, uint16x4x3_t b) {
   vst3_u16(a, b);
 }
 
-// CHECK: test_vst3_u32
+// CHECK-LABEL: test_vst3_u32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_u32(uint32_t * a, uint32x2x3_t b) {
   vst3_u32(a, b);
 }
 
-// CHECK: test_vst3_u64
+// CHECK-LABEL: test_vst3_u64
 // CHECK: vst1.64
 void test_vst3_u64(uint64_t * a, uint64x1x3_t b) {
   vst3_u64(a, b);
 }
 
-// CHECK: test_vst3_s8
+// CHECK-LABEL: test_vst3_s8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_s8(int8_t * a, int8x8x3_t b) {
   vst3_s8(a, b);
 }
 
-// CHECK: test_vst3_s16
+// CHECK-LABEL: test_vst3_s16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_s16(int16_t * a, int16x4x3_t b) {
   vst3_s16(a, b);
 }
 
-// CHECK: test_vst3_s32
+// CHECK-LABEL: test_vst3_s32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_s32(int32_t * a, int32x2x3_t b) {
   vst3_s32(a, b);
 }
 
-// CHECK: test_vst3_s64
+// CHECK-LABEL: test_vst3_s64
 // CHECK: vst1.64
 void test_vst3_s64(int64_t * a, int64x1x3_t b) {
   vst3_s64(a, b);
 }
 
-// CHECK: test_vst3_f16
+// CHECK-LABEL: test_vst3_f16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_f16(float16_t * a, float16x4x3_t b) {
   vst3_f16(a, b);
 }
 
-// CHECK: test_vst3_f32
+// CHECK-LABEL: test_vst3_f32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_f32(float32_t * a, float32x2x3_t b) {
   vst3_f32(a, b);
 }
 
-// CHECK: test_vst3_p8
+// CHECK-LABEL: test_vst3_p8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_p8(poly8_t * a, poly8x8x3_t b) {
   vst3_p8(a, b);
 }
 
-// CHECK: test_vst3_p16
+// CHECK-LABEL: test_vst3_p16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_p16(poly16_t * a, poly16x4x3_t b) {
   vst3_p16(a, b);
 }
 
 
-// CHECK: test_vst3q_lane_u16
+// CHECK-LABEL: test_vst3q_lane_u16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_u16(uint16_t * a, uint16x8x3_t b) {
   vst3q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vst3q_lane_u32
+// CHECK-LABEL: test_vst3q_lane_u32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_u32(uint32_t * a, uint32x4x3_t b) {
   vst3q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vst3q_lane_s16
+// CHECK-LABEL: test_vst3q_lane_s16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_s16(int16_t * a, int16x8x3_t b) {
   vst3q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vst3q_lane_s32
+// CHECK-LABEL: test_vst3q_lane_s32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_s32(int32_t * a, int32x4x3_t b) {
   vst3q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vst3q_lane_f16
+// CHECK-LABEL: test_vst3q_lane_f16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_f16(float16_t * a, float16x8x3_t b) {
   vst3q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vst3q_lane_f32
+// CHECK-LABEL: test_vst3q_lane_f32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_f32(float32_t * a, float32x4x3_t b) {
   vst3q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vst3q_lane_p16
+// CHECK-LABEL: test_vst3q_lane_p16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_p16(poly16_t * a, poly16x8x3_t b) {
   vst3q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vst3_lane_u8
+// CHECK-LABEL: test_vst3_lane_u8
 // CHECK: vst3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_u8(uint8_t * a, uint8x8x3_t b) {
   vst3_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vst3_lane_u16
+// CHECK-LABEL: test_vst3_lane_u16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_u16(uint16_t * a, uint16x4x3_t b) {
   vst3_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vst3_lane_u32
+// CHECK-LABEL: test_vst3_lane_u32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_u32(uint32_t * a, uint32x2x3_t b) {
   vst3_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vst3_lane_s8
+// CHECK-LABEL: test_vst3_lane_s8
 // CHECK: vst3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_s8(int8_t * a, int8x8x3_t b) {
   vst3_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vst3_lane_s16
+// CHECK-LABEL: test_vst3_lane_s16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_s16(int16_t * a, int16x4x3_t b) {
   vst3_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vst3_lane_s32
+// CHECK-LABEL: test_vst3_lane_s32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_s32(int32_t * a, int32x2x3_t b) {
   vst3_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vst3_lane_f16
+// CHECK-LABEL: test_vst3_lane_f16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_f16(float16_t * a, float16x4x3_t b) {
   vst3_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vst3_lane_f32
+// CHECK-LABEL: test_vst3_lane_f32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_f32(float32_t * a, float32x2x3_t b) {
   vst3_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vst3_lane_p8
+// CHECK-LABEL: test_vst3_lane_p8
 // CHECK: vst3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_p8(poly8_t * a, poly8x8x3_t b) {
   vst3_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vst3_lane_p16
+// CHECK-LABEL: test_vst3_lane_p16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_p16(poly16_t * a, poly16x4x3_t b) {
   vst3_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vst4q_u8
+// CHECK-LABEL: test_vst4q_u8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_u8(uint8_t * a, uint8x16x4_t b) {
   vst4q_u8(a, b);
 }
 
-// CHECK: test_vst4q_u16
+// CHECK-LABEL: test_vst4q_u16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_u16(uint16_t * a, uint16x8x4_t b) {
   vst4q_u16(a, b);
 }
 
-// CHECK: test_vst4q_u32
+// CHECK-LABEL: test_vst4q_u32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_u32(uint32_t * a, uint32x4x4_t b) {
   vst4q_u32(a, b);
 }
 
-// CHECK: test_vst4q_s8
+// CHECK-LABEL: test_vst4q_s8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_s8(int8_t * a, int8x16x4_t b) {
   vst4q_s8(a, b);
 }
 
-// CHECK: test_vst4q_s16
+// CHECK-LABEL: test_vst4q_s16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_s16(int16_t * a, int16x8x4_t b) {
   vst4q_s16(a, b);
 }
 
-// CHECK: test_vst4q_s32
+// CHECK-LABEL: test_vst4q_s32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_s32(int32_t * a, int32x4x4_t b) {
   vst4q_s32(a, b);
 }
 
-// CHECK: test_vst4q_f16
+// CHECK-LABEL: test_vst4q_f16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_f16(float16_t * a, float16x8x4_t b) {
   vst4q_f16(a, b);
 }
 
-// CHECK: test_vst4q_f32
+// CHECK-LABEL: test_vst4q_f32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_f32(float32_t * a, float32x4x4_t b) {
   vst4q_f32(a, b);
 }
 
-// CHECK: test_vst4q_p8
+// CHECK-LABEL: test_vst4q_p8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_p8(poly8_t * a, poly8x16x4_t b) {
   vst4q_p8(a, b);
 }
 
-// CHECK: test_vst4q_p16
+// CHECK-LABEL: test_vst4q_p16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_p16(poly16_t * a, poly16x8x4_t b) {
   vst4q_p16(a, b);
 }
 
-// CHECK: test_vst4_u8
+// CHECK-LABEL: test_vst4_u8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_u8(uint8_t * a, uint8x8x4_t b) {
   vst4_u8(a, b);
 }
 
-// CHECK: test_vst4_u16
+// CHECK-LABEL: test_vst4_u16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_u16(uint16_t * a, uint16x4x4_t b) {
   vst4_u16(a, b);
 }
 
-// CHECK: test_vst4_u32
+// CHECK-LABEL: test_vst4_u32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_u32(uint32_t * a, uint32x2x4_t b) {
   vst4_u32(a, b);
 }
 
-// CHECK: test_vst4_u64
+// CHECK-LABEL: test_vst4_u64
 // CHECK: vst1.64
 void test_vst4_u64(uint64_t * a, uint64x1x4_t b) {
   vst4_u64(a, b);
 }
 
-// CHECK: test_vst4_s8
+// CHECK-LABEL: test_vst4_s8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_s8(int8_t * a, int8x8x4_t b) {
   vst4_s8(a, b);
 }
 
-// CHECK: test_vst4_s16
+// CHECK-LABEL: test_vst4_s16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_s16(int16_t * a, int16x4x4_t b) {
   vst4_s16(a, b);
 }
 
-// CHECK: test_vst4_s32
+// CHECK-LABEL: test_vst4_s32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_s32(int32_t * a, int32x2x4_t b) {
   vst4_s32(a, b);
 }
 
-// CHECK: test_vst4_s64
+// CHECK-LABEL: test_vst4_s64
 // CHECK: vst1.64
 void test_vst4_s64(int64_t * a, int64x1x4_t b) {
   vst4_s64(a, b);
 }
 
-// CHECK: test_vst4_f16
+// CHECK-LABEL: test_vst4_f16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_f16(float16_t * a, float16x4x4_t b) {
   vst4_f16(a, b);
 }
 
-// CHECK: test_vst4_f32
+// CHECK-LABEL: test_vst4_f32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_f32(float32_t * a, float32x2x4_t b) {
   vst4_f32(a, b);
 }
 
-// CHECK: test_vst4_p8
+// CHECK-LABEL: test_vst4_p8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_p8(poly8_t * a, poly8x8x4_t b) {
   vst4_p8(a, b);
 }
 
-// CHECK: test_vst4_p16
+// CHECK-LABEL: test_vst4_p16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_p16(poly16_t * a, poly16x4x4_t b) {
   vst4_p16(a, b);
 }
 
 
-// CHECK: test_vst4q_lane_u16
+// CHECK-LABEL: test_vst4q_lane_u16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_u16(uint16_t * a, uint16x8x4_t b) {
   vst4q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vst4q_lane_u32
+// CHECK-LABEL: test_vst4q_lane_u32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_u32(uint32_t * a, uint32x4x4_t b) {
   vst4q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vst4q_lane_s16
+// CHECK-LABEL: test_vst4q_lane_s16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_s16(int16_t * a, int16x8x4_t b) {
   vst4q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vst4q_lane_s32
+// CHECK-LABEL: test_vst4q_lane_s32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_s32(int32_t * a, int32x4x4_t b) {
   vst4q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vst4q_lane_f16
+// CHECK-LABEL: test_vst4q_lane_f16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_f16(float16_t * a, float16x8x4_t b) {
   vst4q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vst4q_lane_f32
+// CHECK-LABEL: test_vst4q_lane_f32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_f32(float32_t * a, float32x4x4_t b) {
   vst4q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vst4q_lane_p16
+// CHECK-LABEL: test_vst4q_lane_p16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_p16(poly16_t * a, poly16x8x4_t b) {
   vst4q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vst4_lane_u8
+// CHECK-LABEL: test_vst4_lane_u8
 // CHECK: vst4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_u8(uint8_t * a, uint8x8x4_t b) {
   vst4_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vst4_lane_u16
+// CHECK-LABEL: test_vst4_lane_u16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_u16(uint16_t * a, uint16x4x4_t b) {
   vst4_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vst4_lane_u32
+// CHECK-LABEL: test_vst4_lane_u32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_u32(uint32_t * a, uint32x2x4_t b) {
   vst4_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vst4_lane_s8
+// CHECK-LABEL: test_vst4_lane_s8
 // CHECK: vst4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_s8(int8_t * a, int8x8x4_t b) {
   vst4_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vst4_lane_s16
+// CHECK-LABEL: test_vst4_lane_s16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_s16(int16_t * a, int16x4x4_t b) {
   vst4_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vst4_lane_s32
+// CHECK-LABEL: test_vst4_lane_s32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_s32(int32_t * a, int32x2x4_t b) {
   vst4_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vst4_lane_f16
+// CHECK-LABEL: test_vst4_lane_f16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_f16(float16_t * a, float16x4x4_t b) {
   vst4_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vst4_lane_f32
+// CHECK-LABEL: test_vst4_lane_f32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_f32(float32_t * a, float32x2x4_t b) {
   vst4_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vst4_lane_p8
+// CHECK-LABEL: test_vst4_lane_p8
 // CHECK: vst4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_p8(poly8_t * a, poly8x8x4_t b) {
   vst4_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vst4_lane_p16
+// CHECK-LABEL: test_vst4_lane_p16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_p16(poly16_t * a, poly16x4x4_t b) {
   vst4_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vsub_s8
+// CHECK-LABEL: test_vsub_s8
 // CHECK: vsub.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vsub_s8(int8x8_t a, int8x8_t b) {
   return vsub_s8(a, b);
 }
 
-// CHECK: test_vsub_s16
+// CHECK-LABEL: test_vsub_s16
 // CHECK: vsub.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vsub_s16(int16x4_t a, int16x4_t b) {
   return vsub_s16(a, b);
 }
 
-// CHECK: test_vsub_s32
+// CHECK-LABEL: test_vsub_s32
 // CHECK: vsub.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vsub_s32(int32x2_t a, int32x2_t b) {
   return vsub_s32(a, b);
 }
 
-// CHECK: test_vsub_s64
+// CHECK-LABEL: test_vsub_s64
 // CHECK: vsub.i64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vsub_s64(int64x1_t a, int64x1_t b) {
   return vsub_s64(a, b);
 }
 
-// CHECK: test_vsub_f32
+// CHECK-LABEL: test_vsub_f32
 // CHECK: vsub.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vsub_f32(float32x2_t a, float32x2_t b) {
   return vsub_f32(a, b);
 }
 
-// CHECK: test_vsub_u8
+// CHECK-LABEL: test_vsub_u8
 // CHECK: vsub.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vsub_u8(uint8x8_t a, uint8x8_t b) {
   return vsub_u8(a, b);
 }
 
-// CHECK: test_vsub_u16
+// CHECK-LABEL: test_vsub_u16
 // CHECK: vsub.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vsub_u16(uint16x4_t a, uint16x4_t b) {
   return vsub_u16(a, b);
 }
 
-// CHECK: test_vsub_u32
+// CHECK-LABEL: test_vsub_u32
 // CHECK: vsub.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vsub_u32(uint32x2_t a, uint32x2_t b) {
   return vsub_u32(a, b);
 }
 
-// CHECK: test_vsub_u64
+// CHECK-LABEL: test_vsub_u64
 // CHECK: vsub.i64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vsub_u64(uint64x1_t a, uint64x1_t b) {
   return vsub_u64(a, b);
 }
 
-// CHECK: test_vsubq_s8
+// CHECK-LABEL: test_vsubq_s8
 // CHECK: vsub.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vsubq_s8(int8x16_t a, int8x16_t b) {
   return vsubq_s8(a, b);
 }
 
-// CHECK: test_vsubq_s16
+// CHECK-LABEL: test_vsubq_s16
 // CHECK: vsub.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vsubq_s16(int16x8_t a, int16x8_t b) {
   return vsubq_s16(a, b);
 }
 
-// CHECK: test_vsubq_s32
+// CHECK-LABEL: test_vsubq_s32
 // CHECK: vsub.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vsubq_s32(int32x4_t a, int32x4_t b) {
   return vsubq_s32(a, b);
 }
 
-// CHECK: test_vsubq_s64
+// CHECK-LABEL: test_vsubq_s64
 // CHECK: vsub.i64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vsubq_s64(int64x2_t a, int64x2_t b) {
   return vsubq_s64(a, b);
 }
 
-// CHECK: test_vsubq_f32
+// CHECK-LABEL: test_vsubq_f32
 // CHECK: vsub.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vsubq_f32(float32x4_t a, float32x4_t b) {
   return vsubq_f32(a, b);
 }
 
-// CHECK: test_vsubq_u8
+// CHECK-LABEL: test_vsubq_u8
 // CHECK: vsub.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vsubq_u8(uint8x16_t a, uint8x16_t b) {
   return vsubq_u8(a, b);
 }
 
-// CHECK: test_vsubq_u16
+// CHECK-LABEL: test_vsubq_u16
 // CHECK: vsub.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vsubq_u16(uint16x8_t a, uint16x8_t b) {
   return vsubq_u16(a, b);
 }
 
-// CHECK: test_vsubq_u32
+// CHECK-LABEL: test_vsubq_u32
 // CHECK: vsub.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vsubq_u32(uint32x4_t a, uint32x4_t b) {
   return vsubq_u32(a, b);
 }
 
-// CHECK: test_vsubq_u64
+// CHECK-LABEL: test_vsubq_u64
 // CHECK: vsub.i64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vsubq_u64(uint64x2_t a, uint64x2_t b) {
   return vsubq_u64(a, b);
 }
 
 
-// CHECK: test_vsubhn_s16
+// CHECK-LABEL: test_vsubhn_s16
 // CHECK: vsubhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vsubhn_s16(int16x8_t a, int16x8_t b) {
   return vsubhn_s16(a, b);
 }
 
-// CHECK: test_vsubhn_s32
+// CHECK-LABEL: test_vsubhn_s32
 // CHECK: vsubhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vsubhn_s32(int32x4_t a, int32x4_t b) {
   return vsubhn_s32(a, b);
 }
 
-// CHECK: test_vsubhn_s64
+// CHECK-LABEL: test_vsubhn_s64
 // CHECK: vsubhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vsubhn_s64(int64x2_t a, int64x2_t b) {
   return vsubhn_s64(a, b);
 }
 
-// CHECK: test_vsubhn_u16
+// CHECK-LABEL: test_vsubhn_u16
 // CHECK: vsubhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vsubhn_u16(uint16x8_t a, uint16x8_t b) {
   return vsubhn_u16(a, b);
 }
 
-// CHECK: test_vsubhn_u32
+// CHECK-LABEL: test_vsubhn_u32
 // CHECK: vsubhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vsubhn_u32(uint32x4_t a, uint32x4_t b) {
   return vsubhn_u32(a, b);
 }
 
-// CHECK: test_vsubhn_u64
+// CHECK-LABEL: test_vsubhn_u64
 // CHECK: vsubhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vsubhn_u64(uint64x2_t a, uint64x2_t b) {
   return vsubhn_u64(a, b);
 }
 
 
-// CHECK: test_vsubl_s8
+// CHECK-LABEL: test_vsubl_s8
 // CHECK: vsubl.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vsubl_s8(int8x8_t a, int8x8_t b) {
   return vsubl_s8(a, b);
 }
 
-// CHECK: test_vsubl_s16
+// CHECK-LABEL: test_vsubl_s16
 // CHECK: vsubl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vsubl_s16(int16x4_t a, int16x4_t b) {
   return vsubl_s16(a, b);
 }
 
-// CHECK: test_vsubl_s32
+// CHECK-LABEL: test_vsubl_s32
 // CHECK: vsubl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vsubl_s32(int32x2_t a, int32x2_t b) {
   return vsubl_s32(a, b);
 }
 
-// CHECK: test_vsubl_u8
+// CHECK-LABEL: test_vsubl_u8
 // CHECK: vsubl.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vsubl_u8(uint8x8_t a, uint8x8_t b) {
   return vsubl_u8(a, b);
 }
 
-// CHECK: test_vsubl_u16
+// CHECK-LABEL: test_vsubl_u16
 // CHECK: vsubl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vsubl_u16(uint16x4_t a, uint16x4_t b) {
   return vsubl_u16(a, b);
 }
 
-// CHECK: test_vsubl_u32
+// CHECK-LABEL: test_vsubl_u32
 // CHECK: vsubl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vsubl_u32(uint32x2_t a, uint32x2_t b) {
   return vsubl_u32(a, b);
 }
 
 
-// CHECK: test_vsubw_s8
+// CHECK-LABEL: test_vsubw_s8
 // CHECK: vsubw.s8 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vsubw_s8(int16x8_t a, int8x8_t b) {
   return vsubw_s8(a, b);
 }
 
-// CHECK: test_vsubw_s16
+// CHECK-LABEL: test_vsubw_s16
 // CHECK: vsubw.s16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vsubw_s16(int32x4_t a, int16x4_t b) {
   return vsubw_s16(a, b);
 }
 
-// CHECK: test_vsubw_s32
+// CHECK-LABEL: test_vsubw_s32
 // CHECK: vsubw.s32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vsubw_s32(int64x2_t a, int32x2_t b) {
   return vsubw_s32(a, b);
 }
 
-// CHECK: test_vsubw_u8
+// CHECK-LABEL: test_vsubw_u8
 // CHECK: vsubw.u8 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vsubw_u8(uint16x8_t a, uint8x8_t b) {
   return vsubw_u8(a, b);
 }
 
-// CHECK: test_vsubw_u16
+// CHECK-LABEL: test_vsubw_u16
 // CHECK: vsubw.u16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vsubw_u16(uint32x4_t a, uint16x4_t b) {
   return vsubw_u16(a, b);
 }
 
-// CHECK: test_vsubw_u32
+// CHECK-LABEL: test_vsubw_u32
 // CHECK: vsubw.u32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vsubw_u32(uint64x2_t a, uint32x2_t b) {
   return vsubw_u32(a, b);
 }
 
 
-// CHECK: test_vtbl1_u8
+// CHECK-LABEL: test_vtbl1_u8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbl1_u8(uint8x8_t a, uint8x8_t b) {
   return vtbl1_u8(a, b);
 }
 
-// CHECK: test_vtbl1_s8
+// CHECK-LABEL: test_vtbl1_s8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbl1_s8(int8x8_t a, int8x8_t b) {
   return vtbl1_s8(a, b);
 }
 
-// CHECK: test_vtbl1_p8
+// CHECK-LABEL: test_vtbl1_p8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbl1_p8(poly8x8_t a, uint8x8_t b) {
   return vtbl1_p8(a, b);
 }
 
 
-// CHECK: test_vtbl2_u8
+// CHECK-LABEL: test_vtbl2_u8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbl2_u8(uint8x8x2_t a, uint8x8_t b) {
   return vtbl2_u8(a, b);
 }
 
-// CHECK: test_vtbl2_s8
+// CHECK-LABEL: test_vtbl2_s8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbl2_s8(int8x8x2_t a, int8x8_t b) {
   return vtbl2_s8(a, b);
 }
 
-// CHECK: test_vtbl2_p8
+// CHECK-LABEL: test_vtbl2_p8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbl2_p8(poly8x8x2_t a, uint8x8_t b) {
   return vtbl2_p8(a, b);
 }
 
 
-// CHECK: test_vtbl3_u8
+// CHECK-LABEL: test_vtbl3_u8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbl3_u8(uint8x8x3_t a, uint8x8_t b) {
   return vtbl3_u8(a, b);
 }
 
-// CHECK: test_vtbl3_s8
+// CHECK-LABEL: test_vtbl3_s8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbl3_s8(int8x8x3_t a, int8x8_t b) {
   return vtbl3_s8(a, b);
 }
 
-// CHECK: test_vtbl3_p8
+// CHECK-LABEL: test_vtbl3_p8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbl3_p8(poly8x8x3_t a, uint8x8_t b) {
   return vtbl3_p8(a, b);
 }
 
 
-// CHECK: test_vtbl4_u8
+// CHECK-LABEL: test_vtbl4_u8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbl4_u8(uint8x8x4_t a, uint8x8_t b) {
   return vtbl4_u8(a, b);
 }
 
-// CHECK: test_vtbl4_s8
+// CHECK-LABEL: test_vtbl4_s8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbl4_s8(int8x8x4_t a, int8x8_t b) {
   return vtbl4_s8(a, b);
 }
 
-// CHECK: test_vtbl4_p8
+// CHECK-LABEL: test_vtbl4_p8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbl4_p8(poly8x8x4_t a, uint8x8_t b) {
   return vtbl4_p8(a, b);
 }
 
 
-// CHECK: test_vtbx1_u8
+// CHECK-LABEL: test_vtbx1_u8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbx1_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vtbx1_u8(a, b, c);
 }
 
-// CHECK: test_vtbx1_s8
+// CHECK-LABEL: test_vtbx1_s8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbx1_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
   return vtbx1_s8(a, b, c);
 }
 
-// CHECK: test_vtbx1_p8
+// CHECK-LABEL: test_vtbx1_p8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbx1_p8(poly8x8_t a, poly8x8_t b, uint8x8_t c) {
   return vtbx1_p8(a, b, c);
 }
 
 
-// CHECK: test_vtbx2_u8
+// CHECK-LABEL: test_vtbx2_u8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbx2_u8(uint8x8_t a, uint8x8x2_t b, uint8x8_t c) {
   return vtbx2_u8(a, b, c);
 }
 
-// CHECK: test_vtbx2_s8
+// CHECK-LABEL: test_vtbx2_s8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbx2_s8(int8x8_t a, int8x8x2_t b, int8x8_t c) {
   return vtbx2_s8(a, b, c);
 }
 
-// CHECK: test_vtbx2_p8
+// CHECK-LABEL: test_vtbx2_p8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbx2_p8(poly8x8_t a, poly8x8x2_t b, uint8x8_t c) {
   return vtbx2_p8(a, b, c);
 }
 
 
-// CHECK: test_vtbx3_u8
+// CHECK-LABEL: test_vtbx3_u8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbx3_u8(uint8x8_t a, uint8x8x3_t b, uint8x8_t c) {
   return vtbx3_u8(a, b, c);
 }
 
-// CHECK: test_vtbx3_s8
+// CHECK-LABEL: test_vtbx3_s8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbx3_s8(int8x8_t a, int8x8x3_t b, int8x8_t c) {
   return vtbx3_s8(a, b, c);
 }
 
-// CHECK: test_vtbx3_p8
+// CHECK-LABEL: test_vtbx3_p8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbx3_p8(poly8x8_t a, poly8x8x3_t b, uint8x8_t c) {
   return vtbx3_p8(a, b, c);
 }
 
 
-// CHECK: test_vtbx4_u8
+// CHECK-LABEL: test_vtbx4_u8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbx4_u8(uint8x8_t a, uint8x8x4_t b, uint8x8_t c) {
   return vtbx4_u8(a, b, c);
 }
 
-// CHECK: test_vtbx4_s8
+// CHECK-LABEL: test_vtbx4_s8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbx4_s8(int8x8_t a, int8x8x4_t b, int8x8_t c) {
   return vtbx4_s8(a, b, c);
 }
 
-// CHECK: test_vtbx4_p8
+// CHECK-LABEL: test_vtbx4_p8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbx4_p8(poly8x8_t a, poly8x8x4_t b, uint8x8_t c) {
   return vtbx4_p8(a, b, c);
 }
 
 
-// CHECK: test_vtrn_s8
+// CHECK-LABEL: test_vtrn_s8
 // CHECK: vtrn.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8x2_t test_vtrn_s8(int8x8_t a, int8x8_t b) {
   return vtrn_s8(a, b);
 }
 
-// CHECK: test_vtrn_s16
+// CHECK-LABEL: test_vtrn_s16
 // CHECK: vtrn.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4x2_t test_vtrn_s16(int16x4_t a, int16x4_t b) {
   return vtrn_s16(a, b);
 }
 
-// CHECK: test_vtrn_s32
+// CHECK-LABEL: test_vtrn_s32
 // CHECK: vtrn.32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2x2_t test_vtrn_s32(int32x2_t a, int32x2_t b) {
   return vtrn_s32(a, b);
 }
 
-// CHECK: test_vtrn_u8
+// CHECK-LABEL: test_vtrn_u8
 // CHECK: vtrn.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8x2_t test_vtrn_u8(uint8x8_t a, uint8x8_t b) {
   return vtrn_u8(a, b);
 }
 
-// CHECK: test_vtrn_u16
+// CHECK-LABEL: test_vtrn_u16
 // CHECK: vtrn.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4x2_t test_vtrn_u16(uint16x4_t a, uint16x4_t b) {
   return vtrn_u16(a, b);
 }
 
-// CHECK: test_vtrn_u32
+// CHECK-LABEL: test_vtrn_u32
 // CHECK: vtrn.32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2x2_t test_vtrn_u32(uint32x2_t a, uint32x2_t b) {
   return vtrn_u32(a, b);
 }
 
-// CHECK: test_vtrn_f32
+// CHECK-LABEL: test_vtrn_f32
 // CHECK: vtrn.32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2x2_t test_vtrn_f32(float32x2_t a, float32x2_t b) {
   return vtrn_f32(a, b);
 }
 
-// CHECK: test_vtrn_p8
+// CHECK-LABEL: test_vtrn_p8
 // CHECK: vtrn.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8x2_t test_vtrn_p8(poly8x8_t a, poly8x8_t b) {
   return vtrn_p8(a, b);
 }
 
-// CHECK: test_vtrn_p16
+// CHECK-LABEL: test_vtrn_p16
 // CHECK: vtrn.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4x2_t test_vtrn_p16(poly16x4_t a, poly16x4_t b) {
   return vtrn_p16(a, b);
 }
 
-// CHECK: test_vtrnq_s8
+// CHECK-LABEL: test_vtrnq_s8
 // CHECK: vtrn.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16x2_t test_vtrnq_s8(int8x16_t a, int8x16_t b) {
   return vtrnq_s8(a, b);
 }
 
-// CHECK: test_vtrnq_s16
+// CHECK-LABEL: test_vtrnq_s16
 // CHECK: vtrn.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8x2_t test_vtrnq_s16(int16x8_t a, int16x8_t b) {
   return vtrnq_s16(a, b);
 }
 
-// CHECK: test_vtrnq_s32
+// CHECK-LABEL: test_vtrnq_s32
 // CHECK: vtrn.32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4x2_t test_vtrnq_s32(int32x4_t a, int32x4_t b) {
   return vtrnq_s32(a, b);
 }
 
-// CHECK: test_vtrnq_u8
+// CHECK-LABEL: test_vtrnq_u8
 // CHECK: vtrn.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16x2_t test_vtrnq_u8(uint8x16_t a, uint8x16_t b) {
   return vtrnq_u8(a, b);
 }
 
-// CHECK: test_vtrnq_u16
+// CHECK-LABEL: test_vtrnq_u16
 // CHECK: vtrn.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8x2_t test_vtrnq_u16(uint16x8_t a, uint16x8_t b) {
   return vtrnq_u16(a, b);
 }
 
-// CHECK: test_vtrnq_u32
+// CHECK-LABEL: test_vtrnq_u32
 // CHECK: vtrn.32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4x2_t test_vtrnq_u32(uint32x4_t a, uint32x4_t b) {
   return vtrnq_u32(a, b);
 }
 
-// CHECK: test_vtrnq_f32
+// CHECK-LABEL: test_vtrnq_f32
 // CHECK: vtrn.32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4x2_t test_vtrnq_f32(float32x4_t a, float32x4_t b) {
   return vtrnq_f32(a, b);
 }
 
-// CHECK: test_vtrnq_p8
+// CHECK-LABEL: test_vtrnq_p8
 // CHECK: vtrn.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16x2_t test_vtrnq_p8(poly8x16_t a, poly8x16_t b) {
   return vtrnq_p8(a, b);
 }
 
-// CHECK: test_vtrnq_p16
+// CHECK-LABEL: test_vtrnq_p16
 // CHECK: vtrn.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8x2_t test_vtrnq_p16(poly16x8_t a, poly16x8_t b) {
   return vtrnq_p16(a, b);
 }
 
 
-// CHECK: test_vtst_s8
+// CHECK-LABEL: test_vtst_s8
 // CHECK: vtst.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vtst_s8(int8x8_t a, int8x8_t b) {
   return vtst_s8(a, b);
 }
 
-// CHECK: test_vtst_s16
+// CHECK-LABEL: test_vtst_s16
 // CHECK: vtst.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vtst_s16(int16x4_t a, int16x4_t b) {
   return vtst_s16(a, b);
 }
 
-// CHECK: test_vtst_s32
+// CHECK-LABEL: test_vtst_s32
 // CHECK: vtst.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vtst_s32(int32x2_t a, int32x2_t b) {
   return vtst_s32(a, b);
 }
 
-// CHECK: test_vtst_u8
+// CHECK-LABEL: test_vtst_u8
 // CHECK: vtst.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vtst_u8(uint8x8_t a, uint8x8_t b) {
   return vtst_u8(a, b);
 }
 
-// CHECK: test_vtst_u16
+// CHECK-LABEL: test_vtst_u16
 // CHECK: vtst.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vtst_u16(uint16x4_t a, uint16x4_t b) {
   return vtst_u16(a, b);
 }
 
-// CHECK: test_vtst_u32
+// CHECK-LABEL: test_vtst_u32
 // CHECK: vtst.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vtst_u32(uint32x2_t a, uint32x2_t b) {
   return vtst_u32(a, b);
 }
 
-// CHECK: test_vtst_p8
+// CHECK-LABEL: test_vtst_p8
 // CHECK: vtst.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vtst_p8(poly8x8_t a, poly8x8_t b) {
   return vtst_p8(a, b);
 }
 
-// CHECK: test_vtst_p16
+// CHECK-LABEL: test_vtst_p16
 // CHECK: vtst.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vtst_p16(poly16x4_t a, poly16x4_t b) {
   return vtst_p16(a, b);
 }
 
-// CHECK: test_vtstq_s8
+// CHECK-LABEL: test_vtstq_s8
 // CHECK: vtst.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vtstq_s8(int8x16_t a, int8x16_t b) {
   return vtstq_s8(a, b);
 }
 
-// CHECK: test_vtstq_s16
+// CHECK-LABEL: test_vtstq_s16
 // CHECK: vtst.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vtstq_s16(int16x8_t a, int16x8_t b) {
   return vtstq_s16(a, b);
 }
 
-// CHECK: test_vtstq_s32
+// CHECK-LABEL: test_vtstq_s32
 // CHECK: vtst.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vtstq_s32(int32x4_t a, int32x4_t b) {
   return vtstq_s32(a, b);
 }
 
-// CHECK: test_vtstq_u8
+// CHECK-LABEL: test_vtstq_u8
 // CHECK: vtst.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vtstq_u8(uint8x16_t a, uint8x16_t b) {
   return vtstq_u8(a, b);
 }
 
-// CHECK: test_vtstq_u16
+// CHECK-LABEL: test_vtstq_u16
 // CHECK: vtst.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vtstq_u16(uint16x8_t a, uint16x8_t b) {
   return vtstq_u16(a, b);
 }
 
-// CHECK: test_vtstq_u32
+// CHECK-LABEL: test_vtstq_u32
 // CHECK: vtst.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vtstq_u32(uint32x4_t a, uint32x4_t b) {
   return vtstq_u32(a, b);
 }
 
-// CHECK: test_vtstq_p8
+// CHECK-LABEL: test_vtstq_p8
 // CHECK: vtst.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vtstq_p8(poly8x16_t a, poly8x16_t b) {
   return vtstq_p8(a, b);
 }
 
-// CHECK: test_vtstq_p16
+// CHECK-LABEL: test_vtstq_p16
 // CHECK: vtst.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vtstq_p16(poly16x8_t a, poly16x8_t b) {
   return vtstq_p16(a, b);
 }
 
 
-// CHECK: test_vuzp_s8
+// CHECK-LABEL: test_vuzp_s8
 // CHECK: vuzp.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8x2_t test_vuzp_s8(int8x8_t a, int8x8_t b) {
   return vuzp_s8(a, b);
 }
 
-// CHECK: test_vuzp_s16
+// CHECK-LABEL: test_vuzp_s16
 // CHECK: vuzp.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4x2_t test_vuzp_s16(int16x4_t a, int16x4_t b) {
   return vuzp_s16(a, b);
 }
 
-// CHECK: test_vuzp_s32
+// CHECK-LABEL: test_vuzp_s32
 // CHECK: {{vtrn|vuzp}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2x2_t test_vuzp_s32(int32x2_t a, int32x2_t b) {
   return vuzp_s32(a, b);
 }
 
-// CHECK: test_vuzp_u8
+// CHECK-LABEL: test_vuzp_u8
 // CHECK: vuzp.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8x2_t test_vuzp_u8(uint8x8_t a, uint8x8_t b) {
   return vuzp_u8(a, b);
 }
 
-// CHECK: test_vuzp_u16
+// CHECK-LABEL: test_vuzp_u16
 // CHECK: vuzp.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4x2_t test_vuzp_u16(uint16x4_t a, uint16x4_t b) {
   return vuzp_u16(a, b);
 }
 
-// CHECK: test_vuzp_u32
+// CHECK-LABEL: test_vuzp_u32
 // CHECK: {{vtrn|vuzp}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2x2_t test_vuzp_u32(uint32x2_t a, uint32x2_t b) {
   return vuzp_u32(a, b);
 }
 
-// CHECK: test_vuzp_f32
+// CHECK-LABEL: test_vuzp_f32
 // CHECK: {{vtrn|vuzp}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2x2_t test_vuzp_f32(float32x2_t a, float32x2_t b) {
   return vuzp_f32(a, b);
 }
 
-// CHECK: test_vuzp_p8
+// CHECK-LABEL: test_vuzp_p8
 // CHECK: vuzp.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8x2_t test_vuzp_p8(poly8x8_t a, poly8x8_t b) {
   return vuzp_p8(a, b);
 }
 
-// CHECK: test_vuzp_p16
+// CHECK-LABEL: test_vuzp_p16
 // CHECK: vuzp.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4x2_t test_vuzp_p16(poly16x4_t a, poly16x4_t b) {
   return vuzp_p16(a, b);
 }
 
-// CHECK: test_vuzpq_s8
+// CHECK-LABEL: test_vuzpq_s8
 // CHECK: vuzp.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16x2_t test_vuzpq_s8(int8x16_t a, int8x16_t b) {
   return vuzpq_s8(a, b);
 }
 
-// CHECK: test_vuzpq_s16
+// CHECK-LABEL: test_vuzpq_s16
 // CHECK: vuzp.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8x2_t test_vuzpq_s16(int16x8_t a, int16x8_t b) {
   return vuzpq_s16(a, b);
 }
 
-// CHECK: test_vuzpq_s32
+// CHECK-LABEL: test_vuzpq_s32
 // CHECK: {{vtrn|vuzp}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4x2_t test_vuzpq_s32(int32x4_t a, int32x4_t b) {
   return vuzpq_s32(a, b);
 }
 
-// CHECK: test_vuzpq_u8
+// CHECK-LABEL: test_vuzpq_u8
 // CHECK: vuzp.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16x2_t test_vuzpq_u8(uint8x16_t a, uint8x16_t b) {
   return vuzpq_u8(a, b);
 }
 
-// CHECK: test_vuzpq_u16
+// CHECK-LABEL: test_vuzpq_u16
 // CHECK: vuzp.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8x2_t test_vuzpq_u16(uint16x8_t a, uint16x8_t b) {
   return vuzpq_u16(a, b);
 }
 
-// CHECK: test_vuzpq_u32
+// CHECK-LABEL: test_vuzpq_u32
 // CHECK: {{vtrn|vuzp}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4x2_t test_vuzpq_u32(uint32x4_t a, uint32x4_t b) {
   return vuzpq_u32(a, b);
 }
 
-// CHECK: test_vuzpq_f32
+// CHECK-LABEL: test_vuzpq_f32
 // CHECK: {{vtrn|vuzp}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4x2_t test_vuzpq_f32(float32x4_t a, float32x4_t b) {
   return vuzpq_f32(a, b);
 }
 
-// CHECK: test_vuzpq_p8
+// CHECK-LABEL: test_vuzpq_p8
 // CHECK: vuzp.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16x2_t test_vuzpq_p8(poly8x16_t a, poly8x16_t b) {
   return vuzpq_p8(a, b);
 }
 
-// CHECK: test_vuzpq_p16
+// CHECK-LABEL: test_vuzpq_p16
 // CHECK: vuzp.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8x2_t test_vuzpq_p16(poly16x8_t a, poly16x8_t b) {
   return vuzpq_p16(a, b);
 }
 
 
-// CHECK: test_vzip_s8
+// CHECK-LABEL: test_vzip_s8
 // CHECK: vzip.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8x2_t test_vzip_s8(int8x8_t a, int8x8_t b) {
   return vzip_s8(a, b);
 }
 
-// CHECK: test_vzip_s16
+// CHECK-LABEL: test_vzip_s16
 // CHECK: vzip.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4x2_t test_vzip_s16(int16x4_t a, int16x4_t b) {
   return vzip_s16(a, b);
 }
 
-// CHECK: test_vzip_s32
+// CHECK-LABEL: test_vzip_s32
 // CHECK: {{vtrn|vzip}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2x2_t test_vzip_s32(int32x2_t a, int32x2_t b) {
   return vzip_s32(a, b);
 }
 
-// CHECK: test_vzip_u8
+// CHECK-LABEL: test_vzip_u8
 // CHECK: vzip.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8x2_t test_vzip_u8(uint8x8_t a, uint8x8_t b) {
   return vzip_u8(a, b);
 }
 
-// CHECK: test_vzip_u16
+// CHECK-LABEL: test_vzip_u16
 // CHECK: vzip.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4x2_t test_vzip_u16(uint16x4_t a, uint16x4_t b) {
   return vzip_u16(a, b);
 }
 
-// CHECK: test_vzip_u32
+// CHECK-LABEL: test_vzip_u32
 // CHECK: {{vtrn|vzip}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2x2_t test_vzip_u32(uint32x2_t a, uint32x2_t b) {
   return vzip_u32(a, b);
 }
 
-// CHECK: test_vzip_f32
+// CHECK-LABEL: test_vzip_f32
 // CHECK: {{vtrn|vzip}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2x2_t test_vzip_f32(float32x2_t a, float32x2_t b) {
   return vzip_f32(a, b);
 }
 
-// CHECK: test_vzip_p8
+// CHECK-LABEL: test_vzip_p8
 // CHECK: vzip.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8x2_t test_vzip_p8(poly8x8_t a, poly8x8_t b) {
   return vzip_p8(a, b);
 }
 
-// CHECK: test_vzip_p16
+// CHECK-LABEL: test_vzip_p16
 // CHECK: vzip.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4x2_t test_vzip_p16(poly16x4_t a, poly16x4_t b) {
   return vzip_p16(a, b);
 }
 
-// CHECK: test_vzipq_s8
+// CHECK-LABEL: test_vzipq_s8
 // CHECK: vzip.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16x2_t test_vzipq_s8(int8x16_t a, int8x16_t b) {
   return vzipq_s8(a, b);
 }
 
-// CHECK: test_vzipq_s16
+// CHECK-LABEL: test_vzipq_s16
 // CHECK: vzip.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8x2_t test_vzipq_s16(int16x8_t a, int16x8_t b) {
   return vzipq_s16(a, b);
 }
 
-// CHECK: test_vzipq_s32
+// CHECK-LABEL: test_vzipq_s32
 // CHECK: {{vtrn|vzip}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4x2_t test_vzipq_s32(int32x4_t a, int32x4_t b) {
   return vzipq_s32(a, b);
 }
 
-// CHECK: test_vzipq_u8
+// CHECK-LABEL: test_vzipq_u8
 // CHECK: vzip.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16x2_t test_vzipq_u8(uint8x16_t a, uint8x16_t b) {
   return vzipq_u8(a, b);
 }
 
-// CHECK: test_vzipq_u16
+// CHECK-LABEL: test_vzipq_u16
 // CHECK: vzip.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8x2_t test_vzipq_u16(uint16x8_t a, uint16x8_t b) {
   return vzipq_u16(a, b);
 }
 
-// CHECK: test_vzipq_u32
+// CHECK-LABEL: test_vzipq_u32
 // CHECK: {{vtrn|vzip}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4x2_t test_vzipq_u32(uint32x4_t a, uint32x4_t b) {
   return vzipq_u32(a, b);
 }
 
-// CHECK: test_vzipq_f32
+// CHECK-LABEL: test_vzipq_f32
 // CHECK: {{vtrn|vzip}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4x2_t test_vzipq_f32(float32x4_t a, float32x4_t b) {
   return vzipq_f32(a, b);
 }
 
-// CHECK: test_vzipq_p8
+// CHECK-LABEL: test_vzipq_p8
 // CHECK: vzip.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16x2_t test_vzipq_p8(poly8x16_t a, poly8x16_t b) {
   return vzipq_p8(a, b);
 }
 
-// CHECK: test_vzipq_p16
+// CHECK-LABEL: test_vzipq_p16
 // CHECK: vzip.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8x2_t test_vzipq_p16(poly16x8_t a, poly16x8_t b) {
   return vzipq_p16(a, b);
diff --git a/test/CodeGen/asan-globals.cpp b/test/CodeGen/asan-globals.cpp
new file mode 100644
index 0000000..2702f1d
--- /dev/null
+++ b/test/CodeGen/asan-globals.cpp
@@ -0,0 +1,32 @@
+// RUN: echo "global:*blacklisted_global*" > %t.blacklist
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist -emit-llvm -o - %s | FileCheck %s
+// RUN: echo "src:%s" > %t.blacklist-src
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist-src -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST-SRC
+// REQUIRES: shell
+
+int global;
+// CHECK: [[GLOBAL_LOC:@.asan_loc_descr[0-9]*]] = private unnamed_addr constant {{.*}} i32 [[@LINE-1]], i32 5
+int dyn_init_global = global;
+// CHECK: [[DYN_INIT_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 5
+int blacklisted_global;
+
+void func() {
+  static int static_var = 0;
+  // CHECK: [[STATIC_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 14
+  const char *literal = "Hello, world!";
+  // CHECK: [[LITERAL_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 25
+}
+
+// CHECK: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// CHECK: ![[GLOBAL]] = metadata !{{{.*}} [[GLOBAL_LOC]], i1 false, i1 false}
+// CHECK: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} [[DYN_INIT_LOC]], i1 true, i1 false}
+// CHECK: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, i1 false, i1 true}
+// CHECK: ![[STATIC_VAR]] = metadata !{{{.*}} [[STATIC_LOC]], i1 false, i1 false}
+// CHECK: ![[LITERAL]] = metadata !{{{.*}} [[LITERAL_LOC]], i1 false, i1 false}
+
+// BLACKLIST-SRC: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// BLACKLIST-SRC: ![[GLOBAL]] = metadata !{{{.*}} null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} null, i1 true, i1 true}
+// BLACKLIST-SRC: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[STATIC_VAR]] = metadata !{{{.*}} null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[LITERAL]] = metadata !{{{.*}} null, i1 false, i1 true}
diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c
index 2517b67..9e6b480 100644
--- a/test/CodeGen/atomic-ops.c
+++ b/test/CodeGen/atomic-ops.c
@@ -15,13 +15,13 @@
 } memory_order;
 
 int fi1(_Atomic(int) *i) {
-  // CHECK: @fi1
+  // CHECK-LABEL: @fi1
   // CHECK: load atomic i32* {{.*}} seq_cst
   return __c11_atomic_load(i, memory_order_seq_cst);
 }
 
 int fi1a(int *i) {
-  // CHECK: @fi1a
+  // CHECK-LABEL: @fi1a
   // CHECK: load atomic i32* {{.*}} seq_cst
   int v;
   __atomic_load(i, &v, memory_order_seq_cst);
@@ -29,60 +29,60 @@
 }
 
 int fi1b(int *i) {
-  // CHECK: @fi1b
+  // CHECK-LABEL: @fi1b
   // CHECK: load atomic i32* {{.*}} seq_cst
   return __atomic_load_n(i, memory_order_seq_cst);
 }
 
 void fi2(_Atomic(int) *i) {
-  // CHECK: @fi2
+  // CHECK-LABEL: @fi2
   // CHECK: store atomic i32 {{.*}} seq_cst
   __c11_atomic_store(i, 1, memory_order_seq_cst);
 }
 
 void fi2a(int *i) {
-  // CHECK: @fi2a
+  // CHECK-LABEL: @fi2a
   // CHECK: store atomic i32 {{.*}} seq_cst
   int v = 1;
   __atomic_store(i, &v, memory_order_seq_cst);
 }
 
 void fi2b(int *i) {
-  // CHECK: @fi2b
+  // CHECK-LABEL: @fi2b
   // CHECK: store atomic i32 {{.*}} seq_cst
   __atomic_store_n(i, 1, memory_order_seq_cst);
 }
 
 int fi3(_Atomic(int) *i) {
-  // CHECK: @fi3
+  // CHECK-LABEL: @fi3
   // CHECK: atomicrmw and
   // CHECK-NOT: and
   return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst);
 }
 
 int fi3a(int *i) {
-  // CHECK: @fi3a
+  // CHECK-LABEL: @fi3a
   // CHECK: atomicrmw xor
   // CHECK-NOT: xor
   return __atomic_fetch_xor(i, 1, memory_order_seq_cst);
 }
 
 int fi3b(int *i) {
-  // CHECK: @fi3b
+  // CHECK-LABEL: @fi3b
   // CHECK: atomicrmw add
   // CHECK: add
   return __atomic_add_fetch(i, 1, memory_order_seq_cst);
 }
 
 int fi3c(int *i) {
-  // CHECK: @fi3c
+  // CHECK-LABEL: @fi3c
   // CHECK: atomicrmw nand
   // CHECK-NOT: and
   return __atomic_fetch_nand(i, 1, memory_order_seq_cst);
 }
 
 int fi3d(int *i) {
-  // CHECK: @fi3d
+  // CHECK-LABEL: @fi3d
   // CHECK: atomicrmw nand
   // CHECK: and
   // CHECK: xor
@@ -90,9 +90,10 @@
 }
 
 _Bool fi4(_Atomic(int) *i) {
-  // CHECK: @fi4
-  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
-  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]]
+  // CHECK-LABEL: @fi4
+  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
+  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
+  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
   // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
   // CHECK: store i32 [[OLD]]
   int cmp = 0;
@@ -100,9 +101,10 @@
 }
 
 _Bool fi4a(int *i) {
-  // CHECK: @fi4
-  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
-  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]]
+  // CHECK-LABEL: @fi4
+  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
+  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
+  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
   // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
   // CHECK: store i32 [[OLD]]
   int cmp = 0;
@@ -111,9 +113,10 @@
 }
 
 _Bool fi4b(int *i) {
-  // CHECK: @fi4
-  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
-  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]]
+  // CHECK-LABEL: @fi4
+  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg weak i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
+  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
+  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
   // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
   // CHECK: store i32 [[OLD]]
   int cmp = 0;
@@ -121,13 +124,13 @@
 }
 
 float ff1(_Atomic(float) *d) {
-  // CHECK: @ff1
+  // CHECK-LABEL: @ff1
   // CHECK: load atomic i32* {{.*}} monotonic
   return __c11_atomic_load(d, memory_order_relaxed);
 }
 
 void ff2(_Atomic(float) *d) {
-  // CHECK: @ff2
+  // CHECK-LABEL: @ff2
   // CHECK: store atomic i32 {{.*}} release
   __c11_atomic_store(d, 1, memory_order_release);
 }
@@ -137,20 +140,20 @@
 }
 
 int* fp1(_Atomic(int*) *p) {
-  // CHECK: @fp1
+  // CHECK-LABEL: @fp1
   // CHECK: load atomic i32* {{.*}} seq_cst
   return __c11_atomic_load(p, memory_order_seq_cst);
 }
 
 int* fp2(_Atomic(int*) *p) {
-  // CHECK: @fp2
+  // CHECK-LABEL: @fp2
   // CHECK: store i32 4
   // CHECK: atomicrmw add {{.*}} monotonic
   return __c11_atomic_fetch_add(p, 1, memory_order_relaxed);
 }
 
 int *fp2a(int **p) {
-  // CHECK: @fp2a
+  // CHECK-LABEL: @fp2a
   // CHECK: store i32 4
   // CHECK: atomicrmw sub {{.*}} monotonic
   // Note, the GNU builtins do not multiply by sizeof(T)!
@@ -158,20 +161,20 @@
 }
 
 _Complex float fc(_Atomic(_Complex float) *c) {
-  // CHECK: @fc
+  // CHECK-LABEL: @fc
   // CHECK: atomicrmw xchg i64*
   return __c11_atomic_exchange(c, 2, memory_order_seq_cst);
 }
 
 typedef struct X { int x; } X;
 X fs(_Atomic(X) *c) {
-  // CHECK: @fs
+  // CHECK-LABEL: @fs
   // CHECK: atomicrmw xchg i32*
   return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst);
 }
 
 X fsa(X *c, X *d) {
-  // CHECK: @fsa
+  // CHECK-LABEL: @fsa
   // CHECK: atomicrmw xchg i32*
   X ret;
   __atomic_exchange(c, d, &ret, memory_order_seq_cst);
@@ -179,7 +182,7 @@
 }
 
 _Bool fsb(_Bool *c) {
-  // CHECK: @fsb
+  // CHECK-LABEL: @fsb
   // CHECK: atomicrmw xchg i8*
   return __atomic_exchange_n(c, 1, memory_order_seq_cst);
 }
@@ -205,7 +208,7 @@
 } seventeen;
 
 int lock_free(struct Incomplete *incomplete) {
-  // CHECK: @lock_free
+  // CHECK-LABEL: @lock_free
 
   // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null)
   __c11_atomic_is_lock_free(3);
@@ -253,7 +256,7 @@
 _Atomic(struct foo) bigAtomic;
 
 void structAtomicStore() {
-  // CHECK: @structAtomicStore
+  // CHECK-LABEL: @structAtomicStore
   struct foo f = {0};
   struct bar b = {0};
   __atomic_store(&smallThing, &b, 5);
@@ -263,7 +266,7 @@
   // CHECK: call void @__atomic_store(i32 512, i8* {{.*}} @bigThing
 }
 void structAtomicLoad() {
-  // CHECK: @structAtomicLoad
+  // CHECK-LABEL: @structAtomicLoad
   struct bar b;
   __atomic_load(&smallThing, &b, 5);
   // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing
@@ -273,7 +276,7 @@
   // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing
 }
 struct foo structAtomicExchange() {
-  // CHECK: @structAtomicExchange
+  // CHECK-LABEL: @structAtomicExchange
   struct foo f = {0};
   struct foo old;
   __atomic_exchange(&f, &bigThing, &old, 5);
@@ -283,7 +286,7 @@
   // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*),
 }
 int structAtomicCmpExchange() {
-  // CHECK: @structAtomicCmpExchange
+  // CHECK-LABEL: @structAtomicCmpExchange
   _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5);
   // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2
 
@@ -298,7 +301,7 @@
 // types.
 _Atomic(int) atomic_init_i = 42;
 
-// CHECK: @atomic_init_foo
+// CHECK-LABEL: @atomic_init_foo
 void atomic_init_foo()
 {
   // CHECK-NOT: }
@@ -321,7 +324,7 @@
   // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acquire monotonic
 
   __c11_atomic_compare_exchange_weak(ptr, ptr2, 43, memory_order_seq_cst, memory_order_acquire);
-  // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst acquire
+  // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst acquire
 
   // Unknown ordering: conservatively pick strongest valid option (for now!).
   __atomic_compare_exchange(ptr2, ptr2, ptr2, 0, memory_order_acq_rel, *ptr2);
@@ -330,7 +333,7 @@
   // Undefined behaviour: don't really care what that last ordering is so leave
   // it out:
   __atomic_compare_exchange_n(ptr2, ptr2, 43, 1, memory_order_seq_cst, 42);
-  // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst
+  // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst
 }
 
 // CHECK-LABEL: @generalFailureOrder
@@ -403,4 +406,45 @@
   // CHECK: br
 }
 
+void generalWeakness(int *ptr, int *ptr2, _Bool weak) {
+  __atomic_compare_exchange_n(ptr, ptr2, 42, weak, memory_order_seq_cst, memory_order_seq_cst);
+  // CHECK: switch i1 {{.*}}, label %[[WEAK:[0-9a-zA-Z._]+]] [
+  // CHECK-NEXT: i1 false, label %[[STRONG:[0-9a-zA-Z._]+]]
+
+  // CHECK: [[STRONG]]
+  // CHECK-NOT: br
+  // CHECK: cmpxchg {{.*}} seq_cst seq_cst
+  // CHECK: br
+
+  // CHECK: [[WEAK]]
+  // CHECK-NOT: br
+  // CHECK: cmpxchg weak {{.*}} seq_cst seq_cst
+  // CHECK: br
+}
+
+// Having checked the flow in the previous two cases, we'll trust clang to
+// combine them sanely.
+void EMIT_ALL_THE_THINGS(int *ptr, int *ptr2, int new, _Bool weak, int success, int fail) {
+  __atomic_compare_exchange(ptr, ptr2, &new, weak, success, fail);
+
+  // CHECK: = cmpxchg {{.*}} monotonic monotonic
+  // CHECK: = cmpxchg weak {{.*}} monotonic monotonic
+  // CHECK: = cmpxchg {{.*}} acquire monotonic
+  // CHECK: = cmpxchg {{.*}} acquire acquire
+  // CHECK: = cmpxchg weak {{.*}} acquire monotonic
+  // CHECK: = cmpxchg weak {{.*}} acquire acquire
+  // CHECK: = cmpxchg {{.*}} release monotonic
+  // CHECK: = cmpxchg weak {{.*}} release monotonic
+  // CHECK: = cmpxchg {{.*}} acq_rel monotonic
+  // CHECK: = cmpxchg {{.*}} acq_rel acquire
+  // CHECK: = cmpxchg weak {{.*}} acq_rel monotonic
+  // CHECK: = cmpxchg weak {{.*}} acq_rel acquire
+  // CHECK: = cmpxchg {{.*}} seq_cst monotonic
+  // CHECK: = cmpxchg {{.*}} seq_cst acquire
+  // CHECK: = cmpxchg {{.*}} seq_cst seq_cst
+  // CHECK: = cmpxchg weak {{.*}} seq_cst monotonic
+  // CHECK: = cmpxchg weak {{.*}} seq_cst acquire
+  // CHECK: = cmpxchg weak {{.*}} seq_cst seq_cst
+}
+
 #endif
diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c
index ac3848f..43f5bc8 100644
--- a/test/CodeGen/atomic.c
+++ b/test/CodeGen/atomic.c
@@ -35,10 +35,12 @@
   // CHECK: atomicrmw xchg i32* %val, i32 8 seq_cst
   
   old = __sync_val_compare_and_swap(&val, 4, 1976);
-  // CHECK: cmpxchg i32* %val, i32 4, i32 1976 seq_cst
-  
+  // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* %val, i32 4, i32 1976 seq_cst
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
+
   old = __sync_bool_compare_and_swap(&val, 4, 1976);
-  // CHECK: cmpxchg i32* %val, i32 4, i32 1976 seq_cst
+  // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* %val, i32 4, i32 1976 seq_cst
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 1
 
   old = __sync_fetch_and_and(&val, 0x9);
   // CHECK: atomicrmw and i32* %val, i32 9 seq_cst
@@ -65,10 +67,13 @@
   // CHECK: atomicrmw xor i8* %valc, i8 5 seq_cst  
   
   __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0);
-  // CHECK: cmpxchg i32* null, i32 0, i32 0 seq_cst
+  // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* null, i32 0, i32 0 seq_cst
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
 
   if ( __sync_val_compare_and_swap(&valb, 0, 1)) {
-    // CHECK: cmpxchg i8* %valb, i8 0, i8 1 seq_cst
+    // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i8* %valb, i8 0, i8 1 seq_cst
+    // CHECK: [[VAL:%[a-z0-9_.]+]] = extractvalue { i8, i1 } [[PAIR]], 0
+    // CHECK: trunc i8 [[VAL]] to i1
     old = 42;
   }
   
diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c
index 388ea82..356a179 100644
--- a/test/CodeGen/attributes.c
+++ b/test/CodeGen/attributes.c
@@ -26,7 +26,7 @@
 // CHECK: @t12 = global i32 0, section "SECT"
 int t12 __attribute__((section("SECT")));
 
-// CHECK: @t9 = alias weak void (...), void ()* @__t8
+// CHECK: @t9 = alias weak bitcast (void ()* @__t8 to void (...)*)
 void __t8() {}
 void t9() __attribute__((weak, alias("__t8")));
 
diff --git a/test/CodeGen/avx-shuffle-builtins.c b/test/CodeGen/avx-shuffle-builtins.c
index d071f82..76e2395 100644
--- a/test/CodeGen/avx-shuffle-builtins.c
+++ b/test/CodeGen/avx-shuffle-builtins.c
@@ -63,3 +63,37 @@
   // CHECK: @llvm.x86.avx.vperm2f128.si.256
   return _mm256_permute2f128_si256(a, b, 0x20);
 }
+
+__m128
+test_mm_broadcast_ss(float const *__a) {
+  // CHECK-LABEL: @test_mm_broadcast_ss
+  // CHECK: insertelement <4 x float> {{.*}}, i32 0
+  // CHECK: insertelement <4 x float> {{.*}}, i32 1
+  // CHECK: insertelement <4 x float> {{.*}}, i32 2
+  // CHECK: insertelement <4 x float> {{.*}}, i32 3
+  return _mm_broadcast_ss(__a);
+}
+
+__m256d
+test_mm256_broadcast_sd(double const *__a) {
+  // CHECK-LABEL: @test_mm256_broadcast_sd
+  // CHECK: insertelement <4 x double> {{.*}}, i32 0
+  // CHECK: insertelement <4 x double> {{.*}}, i32 1
+  // CHECK: insertelement <4 x double> {{.*}}, i32 2
+  // CHECK: insertelement <4 x double> {{.*}}, i32 3
+  return _mm256_broadcast_sd(__a);
+}
+
+__m256
+test_mm256_broadcast_ss(float const *__a) {
+  // CHECK-LABEL: @test_mm256_broadcast_ss
+  // CHECK: insertelement <8 x float> {{.*}}, i32 0
+  // CHECK: insertelement <8 x float> {{.*}}, i32 1
+  // CHECK: insertelement <8 x float> {{.*}}, i32 2
+  // CHECK: insertelement <8 x float> {{.*}}, i32 3
+  // CHECK: insertelement <8 x float> {{.*}}, i32 4
+  // CHECK: insertelement <8 x float> {{.*}}, i32 5
+  // CHECK: insertelement <8 x float> {{.*}}, i32 6
+  // CHECK: insertelement <8 x float> {{.*}}, i32 7
+  return _mm256_broadcast_ss(__a);
+}
diff --git a/test/CodeGen/big-atomic-ops.c b/test/CodeGen/big-atomic-ops.c
index 01a2801..7409661 100644
--- a/test/CodeGen/big-atomic-ops.c
+++ b/test/CodeGen/big-atomic-ops.c
@@ -106,7 +106,7 @@
 
 _Bool fi4b(int *i) {
   // CHECK: @fi4
-  // CHECK: cmpxchg i32*
+  // CHECK: cmpxchg weak i32*
   int cmp = 0;
   return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire);
 }
diff --git a/test/CodeGen/bmi-builtins.c b/test/CodeGen/bmi-builtins.c
index 2e1ba12..92332e3 100644
--- a/test/CodeGen/bmi-builtins.c
+++ b/test/CodeGen/bmi-builtins.c
@@ -5,6 +5,14 @@
 
 #include <x86intrin.h>
 
+// The double underscore intrinsics are for compatibility with 
+// AMD's BMI interface. The single underscore intrinsics
+// are for compatibility with Intel's BMI interface.
+// Apart from the underscores, the interfaces are identical
+// except in one case: although the 'bextr' register-form 
+// instruction is identical in hardware, the AMD and Intel 
+// intrinsics are different! 
+
 unsigned short test__tzcnt_u16(unsigned short __X) {
   // CHECK: @llvm.cttz.i16
   return __tzcnt_u16(__X);
@@ -39,7 +47,7 @@
   return __blsr_u32(__X);
 }
 
-unsigned int test_tzcnt_u32(unsigned int __X) {
+unsigned int test__tzcnt_u32(unsigned int __X) {
   // CHECK: @llvm.cttz.i32
   return __tzcnt_u32(__X);
 }
@@ -77,3 +85,80 @@
   // CHECK: @llvm.cttz.i64
   return __tzcnt_u64(__X);
 }
+
+// Intel intrinsics
+
+unsigned short test_tzcnt_u16(unsigned short __X) {
+  // CHECK: @llvm.cttz.i16
+  return _tzcnt_u16(__X);
+}
+
+unsigned int test_andn_u32(unsigned int __X, unsigned int __Y) {
+  // CHECK: [[DEST:%.*]] = xor i32 %{{.*}}, -1
+  // CHECK-NEXT: %{{.*}} = and i32 %{{.*}}, [[DEST]]
+  return _andn_u32(__X, __Y);
+}
+
+unsigned int test_bextr_u32(unsigned int __X, unsigned int __Y, 
+                            unsigned int __Z) {
+  // CHECK: @llvm.x86.bmi.bextr.32
+  return _bextr_u32(__X, __Y, __Z);
+}
+
+unsigned int test_blsi_u32(unsigned int __X) {
+  // CHECK: [[DEST:%.*]] = sub i32 0, [[SRC:%.*]]
+  // CHECK-NEXT: %{{.*}} = and i32 [[SRC]], [[DEST]]
+  return _blsi_u32(__X);
+}
+
+unsigned int test_blsmsk_u32(unsigned int __X) {
+  // CHECK: [[DEST:%.*]] = add i32 [[SRC:%.*]], -1
+  // CHECK-NEXT: %{{.*}} = xor i32 [[DEST]], [[SRC]]
+  return _blsmsk_u32(__X);
+}
+
+unsigned int test_blsr_u32(unsigned int __X) {
+  // CHECK: [[DEST:%.*]] = add i32 [[SRC:%.*]], -1
+  // CHECK-NEXT: %{{.*}} = and i32 [[DEST]], [[SRC]]
+  return _blsr_u32(__X);
+}
+
+unsigned int test_tzcnt_u32(unsigned int __X) {
+  // CHECK: @llvm.cttz.i32
+  return _tzcnt_u32(__X);
+}
+
+unsigned long long test_andn_u64(unsigned long __X, unsigned long __Y) {
+  // CHECK: [[DEST:%.*]] = xor i64 %{{.*}}, -1
+  // CHECK-NEXT: %{{.*}} = and i64 %{{.*}}, [[DEST]]
+  return _andn_u64(__X, __Y);
+}
+
+unsigned long long test_bextr_u64(unsigned long __X, unsigned int __Y, 
+                                  unsigned int __Z) {
+  // CHECK: @llvm.x86.bmi.bextr.64
+  return _bextr_u64(__X, __Y, __Z);
+}
+
+unsigned long long test_blsi_u64(unsigned long long __X) {
+  // CHECK: [[DEST:%.*]] = sub i64 0, [[SRC:%.*]]
+  // CHECK-NEXT: %{{.*}} = and i64 [[SRC]], [[DEST]]
+  return _blsi_u64(__X);
+}
+
+unsigned long long test_blsmsk_u64(unsigned long long __X) {
+  // CHECK: [[DEST:%.*]] = add i64 [[SRC:%.*]], -1
+  // CHECK-NEXT: %{{.*}} = xor i64 [[DEST]], [[SRC]]
+  return _blsmsk_u64(__X);
+}
+
+unsigned long long test_blsr_u64(unsigned long long __X) {
+  // CHECK: [[DEST:%.*]] = add i64 [[SRC:%.*]], -1
+  // CHECK-NEXT: %{{.*}} = and i64 [[DEST]], [[SRC]]
+  return _blsr_u64(__X);
+}
+
+unsigned long long test_tzcnt_u64(unsigned long long __X) {
+  // CHECK: @llvm.cttz.i64
+  return _tzcnt_u64(__X);
+}
diff --git a/test/CodeGen/builtins-arm-exclusive.c b/test/CodeGen/builtins-arm-exclusive.c
index ea1cfb8..2b10238 100644
--- a/test/CodeGen/builtins-arm-exclusive.c
+++ b/test/CodeGen/builtins-arm-exclusive.c
@@ -1,5 +1,5 @@
 // REQUIRES: arm-registered-target
-// RUN: %clang_cc1 -Wall -Werror -triple thumbv7-linux-gnueabi -fno-signed-char -O3 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Wall -Werror -triple thumbv8-linux-gnueabi -fno-signed-char -O3 -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -Wall -Werror -triple arm64-apple-ios7.0 -O3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARM64
 
 // Make sure the canonical use works before going into smaller details:
@@ -116,6 +116,90 @@
   return sum;
 }
 
+int test_ldaex(char *addr, long long *addr64, float *addrfloat) {
+// CHECK-LABEL: @test_ldaex
+// CHECK-ARM64-LABEL: @test_ldaex
+  int sum = 0;
+  sum += __builtin_arm_ldaex(addr);
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i8(i8* %addr)
+// CHECK: and i32 [[INTRES]], 255
+
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i8(i8* %addr)
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: [[SEXTTMP:%.*]] = shl i32 [[TRUNCRES]], 24
+// CHECK-ARM64: ashr exact i32 [[SEXTTMP]], 24
+
+  sum += __builtin_arm_ldaex((short *)addr);
+// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i16(i16* [[ADDR16]])
+// CHECK: [[TMPSEXT:%.*]] = shl i32 [[INTRES]], 16
+// CHECK: ashr exact i32 [[TMPSEXT]], 16
+
+// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i16(i16* [[ADDR16]])
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: [[TMPSEXT:%.*]] = shl i32 [[TRUNCRES]], 16
+// CHECK-ARM64: ashr exact i32 [[TMPSEXT]], 16
+
+  sum += __builtin_arm_ldaex((int *)addr);
+// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK:  call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]])
+
+// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i32(i32* [[ADDR32]])
+// CHECK-ARM64: trunc i64 [[INTRES]] to i32
+
+  sum += __builtin_arm_ldaex((long long *)addr);
+// CHECK: call { i32, i32 } @llvm.arm.ldaexd(i8* %addr)
+
+// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
+// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
+
+  sum += __builtin_arm_ldaex(addr64);
+// CHECK: [[ADDR64_AS8:%.*]] = bitcast i64* %addr64 to i8*
+// CHECK: call { i32, i32 } @llvm.arm.ldaexd(i8* [[ADDR64_AS8]])
+
+// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* %addr64)
+
+  sum += __builtin_arm_ldaex(addrfloat);
+// CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[INTADDR]])
+// CHECK: bitcast i32 [[INTRES]] to float
+
+// CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i32(i32* [[INTADDR]])
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: bitcast i32 [[TRUNCRES]] to float
+
+  sum += __builtin_arm_ldaex((double *)addr);
+// CHECK: [[STRUCTRES:%.*]] = tail call { i32, i32 } @llvm.arm.ldaexd(i8* %addr)
+// CHECK: [[RESHI:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 1
+// CHECK: [[RESLO:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 0
+// CHECK: [[RESHI64:%.*]] = zext i32 [[RESHI]] to i64
+// CHECK: [[RESLO64:%.*]] = zext i32 [[RESLO]] to i64
+// CHECK: [[RESHIHI:%.*]] = shl nuw i64 [[RESHI64]], 32
+// CHECK: [[INTRES:%.*]] = or i64 [[RESHIHI]], [[RESLO64]]
+// CHECK: bitcast i64 [[INTRES]] to double
+
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: bitcast i64 [[INTRES]] to double
+
+  sum += *__builtin_arm_ldaex((int **)addr);
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]])
+// CHECK: inttoptr i32 [[INTRES]] to i32*
+
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: inttoptr i64 [[INTRES]] to i32*
+
+  sum += __builtin_arm_ldaex((struct Simple **)addr)->a;
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]])
+// CHECK: inttoptr i32 [[INTRES]] to %struct.Simple*
+
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: inttoptr i64 [[INTRES]] to %struct.Simple*
+  return sum;
+}
+
 int test_strex(char *addr) {
 // CHECK-LABEL: @test_strex
 // CHECK-ARM64-LABEL: @test_strex
@@ -166,6 +250,56 @@
   return res;
 }
 
+int test_stlex(char *addr) {
+// CHECK-LABEL: @test_stlex
+// CHECK-ARM64-LABEL: @test_stlex
+  int res = 0;
+  struct Simple var = {0};
+  res |= __builtin_arm_stlex(4, addr);
+// CHECK: call i32 @llvm.arm.stlex.p0i8(i32 4, i8* %addr)
+
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i8(i64 4, i8* %addr)
+
+  res |= __builtin_arm_stlex(42, (short *)addr);
+// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK:  call i32 @llvm.arm.stlex.p0i16(i32 42, i16* [[ADDR16]])
+
+// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK-ARM64:  call i32 @llvm.aarch64.stlxr.p0i16(i64 42, i16* [[ADDR16]])
+
+  res |= __builtin_arm_stlex(42, (int *)addr);
+// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 42, i32* [[ADDR32]])
+
+// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 42, i32* [[ADDR32]])
+
+  res |= __builtin_arm_stlex(42, (long long *)addr);
+// CHECK: call i32 @llvm.arm.stlexd(i32 42, i32 0, i8* %addr)
+
+// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 42, i64* [[ADDR64]])
+
+  res |= __builtin_arm_stlex(2.71828f, (float *)addr);
+// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 1076754509, i32* [[ADDR32]])
+
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 1076754509, i32* [[ADDR32]])
+
+  res |= __builtin_arm_stlex(3.14159, (double *)addr);
+// CHECK: call i32 @llvm.arm.stlexd(i32 -266631570, i32 1074340345, i8* %addr)
+
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 4614256650576692846, i64* [[ADDR64]])
+
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr);
+// CHECK: [[INTVAL:%.*]] = ptrtoint i16* %var to i32
+// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 [[INTVAL]], i32* [[ADDR32]])
+
+// CHECK-ARM64: [[INTVAL:%.*]] = ptrtoint i16* %var to i64
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 [[INTVAL]], i64* [[ADDR64]])
+
+  return res;
+}
+
 void test_clrex() {
 // CHECK-LABEL: @test_clrex
 // CHECK-ARM64-LABEL: @test_clrex
@@ -203,4 +337,31 @@
 // CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8*
 // CHECK-ARM64: [[RES:%.*]] = tail call i32 @llvm.aarch64.stxp(i64 [[VALLO]], i64 [[VALHI]], i8* [[ADDR8]])
 }
+
+__int128 test_ldaex_128(__int128 *addr) {
+// CHECK-ARM64-LABEL: @test_ldaex_128
+
+  return __builtin_arm_ldaex(addr);
+// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8*
+// CHECK-ARM64: [[STRUCTRES:%.*]] = tail call { i64, i64 } @llvm.aarch64.ldaxp(i8* [[ADDR8]])
+// CHECK-ARM64: [[RESHI:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 1
+// CHECK-ARM64: [[RESLO:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 0
+// CHECK-ARM64: [[RESHI64:%.*]] = zext i64 [[RESHI]] to i128
+// CHECK-ARM64: [[RESLO64:%.*]] = zext i64 [[RESLO]] to i128
+// CHECK-ARM64: [[RESHIHI:%.*]] = shl nuw i128 [[RESHI64]], 64
+// CHECK-ARM64: [[INTRES:%.*]] = or i128 [[RESHIHI]], [[RESLO64]]
+// CHECK-ARM64: ret i128 [[INTRES]]
+}
+
+int test_stlex_128(__int128 *addr, __int128 val) {
+// CHECK-ARM64-LABEL: @test_stlex_128
+
+  return __builtin_arm_stlex(val, addr);
+// CHECK-ARM64: [[VALLO:%.*]] = trunc i128 %val to i64
+// CHECK-ARM64: [[VALHI128:%.*]] = lshr i128 %val, 64
+// CHECK-ARM64: [[VALHI:%.*]] = trunc i128 [[VALHI128]] to i64
+// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8*
+// CHECK-ARM64: [[RES:%.*]] = tail call i32 @llvm.aarch64.stlxp(i64 [[VALLO]], i64 [[VALHI]], i8* [[ADDR8]])
+}
+
 #endif
diff --git a/test/CodeGen/builtins-arm-microsoft.c b/test/CodeGen/builtins-arm-microsoft.c
index 682ec91..6f7b3ea 100644
--- a/test/CodeGen/builtins-arm-microsoft.c
+++ b/test/CodeGen/builtins-arm-microsoft.c
@@ -1,10 +1,41 @@
-// RUN: %clang_cc1 -triple thumbv7-windows -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple armv7-eabi -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -emit-llvm -o - %s \
+// RUN:     | FileCheck %s -check-prefix CHECK-MSVC
+// RUN: %clang_cc1 -triple armv7-eabi -emit-llvm %s -o - \
+// RUN:     | FileCheck %s -check-prefix CHECK-EABI
 // REQUIRES: arm-registered-target
 
 void test_yield_intrinsic() {
   __yield();
 }
 
-// CHECK: call void @llvm.arm.hint(i32 1)
+// CHECK-MSVC: call void @llvm.arm.hint(i32 1)
+// CHECK-EABI-NOT: call void @llvm.arm.hint(i32 1)
+
+void wfe() {
+  __wfe();
+}
+
+// CHECK-MSVC: call {{.*}} @llvm.arm.hint(i32 2)
+// CHECK-EABI-NOT: call {{.*}} @llvm.arm.hint(i32 2)
+
+void wfi() {
+  __wfi();
+}
+
+// CHECK-MSVC: call {{.*}} @llvm.arm.hint(i32 3)
+// CHECK-EABI-NOT: call {{.*}} @llvm.arm.hint(i32 3)
+
+void sev() {
+  __sev();
+}
+
+// CHECK-MSVC: call {{.*}} @llvm.arm.hint(i32 4)
+// CHECK-EABI-NOT: call {{.*}} @llvm.arm.hint(i32 4)
+
+void sevl() {
+  __sevl();
+}
+
+// CHECK-MSVC: call {{.*}} @llvm.arm.hint(i32 5)
+// CHECK-EABI-NOT: call {{.*}} @llvm.arm.hint(i32 5)
 
diff --git a/test/CodeGen/builtins-arm.c b/test/CodeGen/builtins-arm.c
index c5e487a..e55183c 100644
--- a/test/CodeGen/builtins-arm.c
+++ b/test/CodeGen/builtins-arm.c
@@ -20,35 +20,43 @@
 }
 
 void yield() {
-  __yield();
+  __builtin_arm_yield();
 }
 
 // CHECK: call {{.*}} @llvm.arm.hint(i32 1)
 
 void wfe() {
-  __wfe();
+  __builtin_arm_wfe();
 }
 
 // CHECK: call {{.*}} @llvm.arm.hint(i32 2)
 
 void wfi() {
-  __wfi();
+  __builtin_arm_wfi();
 }
 
 // CHECK: call {{.*}} @llvm.arm.hint(i32 3)
 
 void sev() {
-  __sev();
+  __builtin_arm_sev();
 }
 
 // CHECK: call {{.*}} @llvm.arm.hint(i32 4)
 
 void sevl() {
-  __sevl();
+  __builtin_arm_sevl();
 }
+
 // CHECK: call {{.*}} @llvm.arm.hint(i32 5)
 
 void test_barrier() {
   __builtin_arm_dmb(1); //CHECK: call {{.*}} @llvm.arm.dmb(i32 1)
   __builtin_arm_dsb(2); //CHECK: call {{.*}} @llvm.arm.dsb(i32 2)
+  __builtin_arm_isb(3); //CHECK: call {{.*}} @llvm.arm.isb(i32 3)
+}
+
+// CHECK: call {{.*}} @llvm.arm.rbit(i32 %a)
+
+unsigned rbit(unsigned a) {
+  return __builtin_arm_rbit(a);
 }
diff --git a/test/CodeGen/builtins-arm64.c b/test/CodeGen/builtins-arm64.c
index fcda92e..9e3460c 100644
--- a/test/CodeGen/builtins-arm64.c
+++ b/test/CodeGen/builtins-arm64.c
@@ -4,3 +4,13 @@
 	__clear_cache(a,b);
 // CHECK: call {{.*}} @__clear_cache
 }
+
+// CHECK: call {{.*}} @llvm.aarch64.rbit.i32(i32 %a)
+unsigned rbit(unsigned a) {
+  return __builtin_arm_rbit(a);
+}
+
+// CHECK: call {{.*}} @llvm.aarch64.rbit.i64(i64 %a)
+unsigned long long rbit64(unsigned long long a) {
+  return __builtin_arm_rbit64(a);
+}
diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c
index 5cd8d32..b161426 100644
--- a/test/CodeGen/builtins-ppc-altivec.c
+++ b/test/CodeGen/builtins-ppc-altivec.c
@@ -1,5 +1,7 @@
 // REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-LE
 
 vector bool char vbc = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
 vector signed char vsc = { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16 };
@@ -45,1267 +47,3769 @@
 void test1() {
 
   /* vec_abs */
-  vsc = vec_abs(vsc);                           // CHECK: sub <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vmaxsb
+  vsc = vec_abs(vsc);
+// CHECK: sub <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: sub <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
 
-  vs = vec_abs(vs);                             // CHECK: sub <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vmaxsh
+  vs = vec_abs(vs);
+// CHECK: sub <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: sub <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
 
-  vi = vec_abs(vi);                             // CHECK: sub <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vmaxsw
+  vi = vec_abs(vi);
+// CHECK: sub <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: sub <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
 
-  vf = vec_abs(vf);                             // CHECK: and <4 x i32>
+  vf = vec_abs(vf);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
 
   /* vec_abs */
-  vsc = vec_abss(vsc);                          // CHECK: @llvm.ppc.altivec.vsubsbs
-                                                // CHECK: @llvm.ppc.altivec.vmaxsb
+  vsc = vec_abss(vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
 
-  vs = vec_abss(vs);                            // CHECK: @llvm.ppc.altivec.vsubshs
-                                                // CHECK: @llvm.ppc.altivec.vmaxsh
+  vs = vec_abss(vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
 
-  vi = vec_abss(vi);                            // CHECK: @llvm.ppc.altivec.vsubsws
-                                                // CHECK: @llvm.ppc.altivec.vmaxsw
+  vi = vec_abss(vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
 
   /*  vec_add */
-  res_vsc = vec_add(vsc, vsc);                  // CHECK: add <16 x i8>
-  res_vsc = vec_add(vbc, vsc);                  // CHECK: add <16 x i8>
-  res_vsc = vec_add(vsc, vbc);                  // CHECK: add <16 x i8>
-  res_vuc = vec_add(vuc, vuc);                  // CHECK: add <16 x i8>
-  res_vuc = vec_add(vbc, vuc);                  // CHECK: add <16 x i8>
-  res_vuc = vec_add(vuc, vbc);                  // CHECK: add <16 x i8>
-  res_vs  = vec_add(vs, vs);                    // CHECK: add <8 x i16>
-  res_vs  = vec_add(vbs, vs);                   // CHECK: add <8 x i16>
-  res_vs  = vec_add(vs, vbs);                   // CHECK: add <8 x i16>
-  res_vus = vec_add(vus, vus);                  // CHECK: add <8 x i16>
-  res_vus = vec_add(vbs, vus);                  // CHECK: add <8 x i16>
-  res_vus = vec_add(vus, vbs);                  // CHECK: add <8 x i16>
-  res_vi  = vec_add(vi, vi);                    // CHECK: add <4 x i32>
-  res_vi  = vec_add(vbi, vi);                   // CHECK: add <4 x i32>
-  res_vi  = vec_add(vi, vbi);                   // CHECK: add <4 x i32>
-  res_vui = vec_add(vui, vui);                  // CHECK: add <4 x i32>
-  res_vui = vec_add(vbi, vui);                  // CHECK: add <4 x i32>
-  res_vui = vec_add(vui, vbi);                  // CHECK: add <4 x i32>
-  res_vf  = vec_add(vf, vf);                    // CHECK: fadd <4 x float>
-  res_vsc = vec_vaddubm(vsc, vsc);              // CHECK: add <16 x i8>
-  res_vsc = vec_vaddubm(vbc, vsc);              // CHECK: add <16 x i8>
-  res_vsc = vec_vaddubm(vsc, vbc);              // CHECK: add <16 x i8>
-  res_vuc = vec_vaddubm(vuc, vuc);              // CHECK: add <16 x i8>
-  res_vuc = vec_vaddubm(vbc, vuc);              // CHECK: add <16 x i8>
-  res_vuc = vec_vaddubm(vuc, vbc);              // CHECK: add <16 x i8>
-  res_vs  = vec_vadduhm(vs, vs);                // CHECK: add <8 x i16>
-  res_vs  = vec_vadduhm(vbs, vs);               // CHECK: add <8 x i16>
-  res_vs  = vec_vadduhm(vs, vbs);               // CHECK: add <8 x i16>
-  res_vus = vec_vadduhm(vus, vus);              // CHECK: add <8 x i16>
-  res_vus = vec_vadduhm(vbs, vus);              // CHECK: add <8 x i16>
-  res_vus = vec_vadduhm(vus, vbs);              // CHECK: add <8 x i16>
-  res_vi  = vec_vadduwm(vi, vi);                // CHECK: add <4 x i32>
-  res_vi  = vec_vadduwm(vbi, vi);               // CHECK: add <4 x i32>
-  res_vi  = vec_vadduwm(vi, vbi);               // CHECK: add <4 x i32>
-  res_vui = vec_vadduwm(vui, vui);              // CHECK: add <4 x i32>
-  res_vui = vec_vadduwm(vbi, vui);              // CHECK: add <4 x i32>
-  res_vui = vec_vadduwm(vui, vbi);              // CHECK: add <4 x i32>
-  res_vf  = vec_vaddfp(vf, vf);                 // CHECK: fadd <4 x float>
+  res_vsc = vec_add(vsc, vsc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vsc = vec_add(vbc, vsc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vsc = vec_add(vsc, vbc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_add(vuc, vuc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_add(vbc, vuc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_add(vuc, vbc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vs  = vec_add(vs, vs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vs  = vec_add(vbs, vs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vs  = vec_add(vs, vbs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_add(vus, vus);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_add(vbs, vus);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_add(vus, vbs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vi  = vec_add(vi, vi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vi  = vec_add(vbi, vi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vi  = vec_add(vi, vbi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_add(vui, vui);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_add(vbi, vui);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_add(vui, vbi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vf  = vec_add(vf, vf);
+// CHECK: fadd <4 x float>
+// CHECK-LE: fadd <4 x float>
+
+  res_vsc = vec_vaddubm(vsc, vsc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vsc = vec_vaddubm(vbc, vsc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vsc = vec_vaddubm(vsc, vbc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_vaddubm(vuc, vuc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_vaddubm(vbc, vuc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_vaddubm(vuc, vbc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vs  = vec_vadduhm(vs, vs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vs  = vec_vadduhm(vbs, vs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vs  = vec_vadduhm(vs, vbs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_vadduhm(vus, vus);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_vadduhm(vbs, vus);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_vadduhm(vus, vbs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vi  = vec_vadduwm(vi, vi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vi  = vec_vadduwm(vbi, vi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vi  = vec_vadduwm(vi, vbi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_vadduwm(vui, vui);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_vadduwm(vbi, vui);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_vadduwm(vui, vbi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vf  = vec_vaddfp(vf, vf);
+// CHECK: fadd <4 x float>
+// CHECK-LE: fadd <4 x float>
 
   /* vec_addc */
-  res_vui = vec_addc(vui, vui);                 // HECK: @llvm.ppc.altivec.vaddcuw
-  res_vui = vec_vaddcuw(vui, vui);              // HECK: @llvm.ppc.altivec.vaddcuw
+  res_vui = vec_addc(vui, vui);
+// CHECK: @llvm.ppc.altivec.vaddcuw
+// CHECK-LE: @llvm.ppc.altivec.vaddcuw
+
+  res_vui = vec_vaddcuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vaddcuw
+// CHECK-LE: @llvm.ppc.altivec.vaddcuw
 
   /* vec_adds */
-  res_vsc = vec_adds(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vsc = vec_adds(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vsc = vec_adds(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vuc = vec_adds(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vuc = vec_adds(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vuc = vec_adds(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vs  = vec_adds(vs, vs);                   // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vs  = vec_adds(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vs  = vec_adds(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vus = vec_adds(vus, vus);                 // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vus = vec_adds(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vus = vec_adds(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vi  = vec_adds(vi, vi);                   // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vi  = vec_adds(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vi  = vec_adds(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vui = vec_adds(vui, vui);                 // CHECK: @llvm.ppc.altivec.vadduws
-  res_vui = vec_adds(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vadduws
-  res_vui = vec_adds(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vadduws
-  res_vsc = vec_vaddsbs(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vsc = vec_vaddsbs(vbc, vsc);              // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vsc = vec_vaddsbs(vsc, vbc);              // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vuc = vec_vaddubs(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vuc = vec_vaddubs(vbc, vuc);              // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vuc = vec_vaddubs(vuc, vbc);              // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vs  = vec_vaddshs(vs, vs);                // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vs  = vec_vaddshs(vbs, vs);               // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vs  = vec_vaddshs(vs, vbs);               // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vus = vec_vadduhs(vus, vus);              // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vus = vec_vadduhs(vbs, vus);              // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vus = vec_vadduhs(vus, vbs);              // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vi  = vec_vaddsws(vi, vi);                // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vi  = vec_vaddsws(vbi, vi);               // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vi  = vec_vaddsws(vi, vbi);               // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vui = vec_vadduws(vui, vui);              // CHECK: @llvm.ppc.altivec.vadduws
-  res_vui = vec_vadduws(vbi, vui);              // CHECK: @llvm.ppc.altivec.vadduws
-  res_vui = vec_vadduws(vui, vbi);              // CHECK: @llvm.ppc.altivec.vadduws
+  res_vsc = vec_adds(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vsc = vec_adds(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vsc = vec_adds(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vuc = vec_adds(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vuc = vec_adds(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vuc = vec_adds(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vs  = vec_adds(vs, vs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vs  = vec_adds(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vs  = vec_adds(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vus = vec_adds(vus, vus);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vus = vec_adds(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vus = vec_adds(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vi  = vec_adds(vi, vi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vi  = vec_adds(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vi  = vec_adds(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vui = vec_adds(vui, vui);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vui = vec_adds(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vui = vec_adds(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vsc = vec_vaddsbs(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vsc = vec_vaddsbs(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vsc = vec_vaddsbs(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vuc = vec_vaddubs(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vuc = vec_vaddubs(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vuc = vec_vaddubs(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vs  = vec_vaddshs(vs, vs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vs  = vec_vaddshs(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vs  = vec_vaddshs(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vus = vec_vadduhs(vus, vus);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vus = vec_vadduhs(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vus = vec_vadduhs(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vi  = vec_vaddsws(vi, vi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vi  = vec_vaddsws(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vi  = vec_vaddsws(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vui = vec_vadduws(vui, vui);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vui = vec_vadduws(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vui = vec_vadduws(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
 
   /* vec_and */
-  res_vsc = vec_and(vsc, vsc);                  // CHECK: and <16 x i8>
-  res_vsc = vec_and(vbc, vsc);                  // CHECK: and <16 x i8>
-  res_vsc = vec_and(vsc, vbc);                  // CHECK: and <16 x i8>
-  res_vuc = vec_and(vuc, vuc);                  // CHECK: and <16 x i8>
-  res_vuc = vec_and(vbc, vuc);                  // CHECK: and <16 x i8>
-  res_vuc = vec_and(vuc, vbc);                  // CHECK: and <16 x i8>
-  res_vbc = vec_and(vbc, vbc);                  // CHECK: and <16 x i8>
-  res_vs  = vec_and(vs, vs);                    // CHECK: and <8 x i16>
-  res_vs  = vec_and(vbs, vs);                   // CHECK: and <8 x i16>
-  res_vs  = vec_and(vs, vbs);                   // CHECK: and <8 x i16>
-  res_vus = vec_and(vus, vus);                  // CHECK: and <8 x i16>
-  res_vus = vec_and(vbs, vus);                  // CHECK: and <8 x i16>
-  res_vus = vec_and(vus, vbs);                  // CHECK: and <8 x i16>
-  res_vbs = vec_and(vbs, vbs);                  // CHECK: and <8 x i16>
-  res_vi  = vec_and(vi, vi);                    // CHECK: and <4 x i32>
-  res_vi  = vec_and(vbi, vi);                   // CHECK: and <4 x i32>
-  res_vi  = vec_and(vi, vbi);                   // CHECK: and <4 x i32>
-  res_vui = vec_and(vui, vui);                  // CHECK: and <4 x i32>
-  res_vui = vec_and(vbi, vui);                  // CHECK: and <4 x i32>
-  res_vui = vec_and(vui, vbi);                  // CHECK: and <4 x i32>
-  res_vbi = vec_and(vbi, vbi);                  // CHECK: and <4 x i32>
-  res_vsc = vec_vand(vsc, vsc);                 // CHECK: and <16 x i8>
-  res_vsc = vec_vand(vbc, vsc);                 // CHECK: and <16 x i8>
-  res_vsc = vec_vand(vsc, vbc);                 // CHECK: and <16 x i8>
-  res_vuc = vec_vand(vuc, vuc);                 // CHECK: and <16 x i8>
-  res_vuc = vec_vand(vbc, vuc);                 // CHECK: and <16 x i8>
-  res_vuc = vec_vand(vuc, vbc);                 // CHECK: and <16 x i8>
-  res_vbc = vec_vand(vbc, vbc);                 // CHECK: and <16 x i8>
-  res_vs  = vec_vand(vs, vs);                   // CHECK: and <8 x i16>
-  res_vs  = vec_vand(vbs, vs);                  // CHECK: and <8 x i16>
-  res_vs  = vec_vand(vs, vbs);                  // CHECK: and <8 x i16>
-  res_vus = vec_vand(vus, vus);                 // CHECK: and <8 x i16>
-  res_vus = vec_vand(vbs, vus);                 // CHECK: and <8 x i16>
-  res_vus = vec_vand(vus, vbs);                 // CHECK: and <8 x i16>
-  res_vbs = vec_vand(vbs, vbs);                 // CHECK: and <8 x i16>
-  res_vi  = vec_vand(vi, vi);                   // CHECK: and <4 x i32>
-  res_vi  = vec_vand(vbi, vi);                  // CHECK: and <4 x i32>
-  res_vi  = vec_vand(vi, vbi);                  // CHECK: and <4 x i32>
-  res_vui = vec_vand(vui, vui);                 // CHECK: and <4 x i32>
-  res_vui = vec_vand(vbi, vui);                 // CHECK: and <4 x i32>
-  res_vui = vec_vand(vui, vbi);                 // CHECK: and <4 x i32>
-  res_vbi = vec_vand(vbi, vbi);                 // CHECK: and <4 x i32>
+  res_vsc = vec_and(vsc, vsc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vsc = vec_and(vbc, vsc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vsc = vec_and(vsc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_and(vuc, vuc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_and(vbc, vuc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_and(vuc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vbc = vec_and(vbc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vs  = vec_and(vs, vs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vs  = vec_and(vbs, vs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vs  = vec_and(vs, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_and(vus, vus);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_and(vbs, vus);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_and(vus, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vbs = vec_and(vbs, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vi  = vec_and(vi, vi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vi  = vec_and(vbi, vi);
+// CHECK: and <4 x i32>
+// CHECK-le: and <4 x i32>
+
+  res_vi  = vec_and(vi, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_and(vui, vui);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_and(vbi, vui);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_and(vui, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vbi = vec_and(vbi, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vsc = vec_vand(vsc, vsc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vsc = vec_vand(vbc, vsc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vsc = vec_vand(vsc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_vand(vuc, vuc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_vand(vbc, vuc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_vand(vuc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vbc = vec_vand(vbc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vs  = vec_vand(vs, vs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vs  = vec_vand(vbs, vs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vs  = vec_vand(vs, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_vand(vus, vus);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_vand(vbs, vus);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_vand(vus, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vbs = vec_vand(vbs, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vi  = vec_vand(vi, vi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vi  = vec_vand(vbi, vi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vi  = vec_vand(vi, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_vand(vui, vui);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_vand(vbi, vui);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_vand(vui, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vbi = vec_vand(vbi, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
 
   /* vec_andc */
-  res_vsc = vec_andc(vsc, vsc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_andc(vsc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vsc = vec_andc(vbc, vsc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_andc(vbc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vsc = vec_andc(vsc, vbc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_andc(vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_andc(vuc, vuc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_andc(vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_andc(vbc, vuc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_andc(vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_andc(vuc, vbc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_andc(vuc, vbc);
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vbc = vec_andc(vbc, vbc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vbc = vec_andc(vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vs  = vec_andc(vs, vs);                   // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_andc(vs, vs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vs  = vec_andc(vbs, vs);                  // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_andc(vbs, vs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vs  = vec_andc(vs, vbs);                  // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_andc(vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_andc(vus, vus);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_andc(vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_andc(vbs, vus);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_andc(vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_andc(vus, vbs);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_andc(vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vbs = vec_andc(vbs, vbs);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vbs = vec_andc(vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vi  = vec_andc(vi, vi);                   // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_andc(vi, vi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vi  = vec_andc(vbi, vi);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_andc(vbi, vi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vi  = vec_andc(vi, vbi);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_andc(vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_andc(vui, vui);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_andc(vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_andc(vbi, vui);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_andc(vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_andc(vui, vbi);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_andc(vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_andc(vf, vf);                    // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_andc(vf, vf);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_andc(vbi, vf);                   // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_andc(vbi, vf);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_andc(vf, vbi);                   // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_andc(vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vsc = vec_vandc(vsc, vsc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_vandc(vsc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vsc = vec_vandc(vbc, vsc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_vandc(vbc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vsc = vec_vandc(vsc, vbc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_vandc(vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_vandc(vuc, vuc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_vandc(vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_vandc(vbc, vuc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_vandc(vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_vandc(vuc, vbc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_vandc(vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vbc = vec_vandc(vbc, vbc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vbc = vec_vandc(vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vs  = vec_vandc(vs, vs);                  // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_vandc(vs, vs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vs  = vec_vandc(vbs, vs);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_vandc(vbs, vs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vs  = vec_vandc(vs, vbs);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_vandc(vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_vandc(vus, vus);                // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_vandc(vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_vandc(vbs, vus);                // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_vandc(vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_vandc(vus, vbs);                // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_vandc(vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vbs = vec_vandc(vbs, vbs);                // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vbs = vec_vandc(vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vi  = vec_vandc(vi, vi);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_vandc(vi, vi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vi  = vec_vandc(vbi, vi);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_vandc(vbi, vi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vi  = vec_vandc(vi, vbi);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_vandc(vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_vandc(vui, vui);                // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_vandc(vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_vandc(vbi, vui);                // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_vandc(vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_vandc(vui, vbi);                // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_vandc(vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_vandc(vf, vf);                   // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_vandc(vf, vf);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_vandc(vbi, vf);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_vandc(vbi, vf);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_vandc(vf, vbi);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_vandc(vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
 }
 
 // CHECK-LABEL: define void @test2
 void test2() {
   /* vec_avg */
-  res_vsc = vec_avg(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vavgsb
-  res_vuc = vec_avg(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vavgub
-  res_vs  = vec_avg(vs, vs);                    // CHECK: @llvm.ppc.altivec.vavgsh
-  res_vus = vec_avg(vus, vus);                  // CHECK: @llvm.ppc.altivec.vavguh
-  res_vi  = vec_avg(vi, vi);                    // CHECK: @llvm.ppc.altivec.vavgsw
-  res_vui = vec_avg(vui, vui);                  // CHECK: @llvm.ppc.altivec.vavguw
-  res_vsc = vec_vavgsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vavgsb
-  res_vuc = vec_vavgub(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vavgub
-  res_vs  = vec_vavgsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vavgsh
-  res_vus = vec_vavguh(vus, vus);               // CHECK: @llvm.ppc.altivec.vavguh
-  res_vi  = vec_vavgsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vavgsw
-  res_vui = vec_vavguw(vui, vui);               // CHECK: @llvm.ppc.altivec.vavguw
+  res_vsc = vec_avg(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vavgsb
+// CHECK-LE: @llvm.ppc.altivec.vavgsb
+
+  res_vuc = vec_avg(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vavgub
+// CHECK-LE: @llvm.ppc.altivec.vavgub
+
+  res_vs  = vec_avg(vs, vs);
+// CHECK: @llvm.ppc.altivec.vavgsh
+// CHECK-LE: @llvm.ppc.altivec.vavgsh
+
+  res_vus = vec_avg(vus, vus);
+// CHECK: @llvm.ppc.altivec.vavguh
+// CHECK-LE: @llvm.ppc.altivec.vavguh
+
+  res_vi  = vec_avg(vi, vi);
+// CHECK: @llvm.ppc.altivec.vavgsw
+// CHECK-LE: @llvm.ppc.altivec.vavgsw
+
+  res_vui = vec_avg(vui, vui);
+// CHECK: @llvm.ppc.altivec.vavguw
+// CHECK-LE: @llvm.ppc.altivec.vavguw
+
+  res_vsc = vec_vavgsb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vavgsb
+// CHECK-LE: @llvm.ppc.altivec.vavgsb
+
+  res_vuc = vec_vavgub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vavgub
+// CHECK-LE: @llvm.ppc.altivec.vavgub
+
+  res_vs  = vec_vavgsh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vavgsh
+// CHECK-LE: @llvm.ppc.altivec.vavgsh
+
+  res_vus = vec_vavguh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vavguh
+// CHECK-LE: @llvm.ppc.altivec.vavguh
+
+  res_vi  = vec_vavgsw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vavgsw
+// CHECK-LE: @llvm.ppc.altivec.vavgsw
+
+  res_vui = vec_vavguw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vavguw
+// CHECK-LE: @llvm.ppc.altivec.vavguw
 
   /* vec_ceil */
-  res_vf = vec_ceil(vf);                        // CHECK: @llvm.ppc.altivec.vrfip
-  res_vf = vec_vrfip(vf);                       // CHECK: @llvm.ppc.altivec.vrfip
+  res_vf = vec_ceil(vf);
+// CHECK: @llvm.ppc.altivec.vrfip
+// CHECK-LE: @llvm.ppc.altivec.vrfip
+
+  res_vf = vec_vrfip(vf);
+// CHECK: @llvm.ppc.altivec.vrfip
+// CHECK-LE: @llvm.ppc.altivec.vrfip
 
   /* vec_cmpb */
-  res_vi = vec_cmpb(vf, vf);                    // CHECK: @llvm.ppc.altivec.vcmpbfp
-  res_vi = vec_vcmpbfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vcmpbfp
+  res_vi = vec_cmpb(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpbfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpbfp
+
+  res_vi = vec_vcmpbfp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpbfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpbfp
 
   /* vec_cmpeq */
-  res_vbc = vec_cmpeq(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpequb
-  res_vbc = vec_cmpeq(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpequb
-  res_vbs = vec_cmpeq(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh
-  res_vbs = vec_cmpeq(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpequh
-  res_vbi = vec_cmpeq(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw
-  res_vbi = vec_cmpeq(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpequw
-  res_vbi = vec_cmpeq(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp
+  res_vbc = vec_cmpeq(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb
+
+  res_vbc = vec_cmpeq(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb
+
+  res_vbs = vec_cmpeq(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh
+
+  res_vbs = vec_cmpeq(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh
+
+  res_vbi = vec_cmpeq(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw
+
+  res_vbi = vec_cmpeq(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw
+
+  res_vbi = vec_cmpeq(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp
 
   /* vec_cmpge */
-  res_vbi = vec_cmpge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp
-  res_vbi = vec_vcmpgefp(vf, vf);               // CHECK: @llvm.ppc.altivec.vcmpgefp
+  res_vbi = vec_cmpge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp
+
+  res_vbi = vec_vcmpgefp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp
 }
 
 // CHECK-LABEL: define void @test5
 void test5() {
-  
+
   /* vec_cmpgt */
-  res_vbc = vec_cmpgt(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpgtsb
-  res_vbc = vec_cmpgt(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpgtub
-  res_vbs = vec_cmpgt(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh
-  res_vbs = vec_cmpgt(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpgtuh
-  res_vbi = vec_cmpgt(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw
-  res_vbi = vec_cmpgt(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpgtuw
-  res_vbi = vec_cmpgt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp
-  res_vbc = vec_vcmpgtsb(vsc, vsc);             // CHECK: @llvm.ppc.altivec.vcmpgtsb
-  res_vbc = vec_vcmpgtub(vuc, vuc);             // CHECK: @llvm.ppc.altivec.vcmpgtub
-  res_vbs = vec_vcmpgtsh(vs, vs);               // CHECK: @llvm.ppc.altivec.vcmpgtsh
-  res_vbs = vec_vcmpgtuh(vus, vus);             // CHECK: @llvm.ppc.altivec.vcmpgtuh
-  res_vbi = vec_vcmpgtsw(vi, vi);               // CHECK: @llvm.ppc.altivec.vcmpgtsw
-  res_vbi = vec_vcmpgtuw(vui, vui);             // CHECK: @llvm.ppc.altivec.vcmpgtuw
-  res_vbi = vec_vcmpgtfp(vf, vf);               // CHECK: @llvm.ppc.altivec.vcmpgtfp
+  res_vbc = vec_cmpgt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb
+
+  res_vbc = vec_cmpgt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub
+
+  res_vbs = vec_cmpgt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh
+
+  res_vbs = vec_cmpgt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh
+
+  res_vbi = vec_cmpgt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw
+
+  res_vbi = vec_cmpgt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw
+
+  res_vbi = vec_cmpgt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp
+
+  res_vbc = vec_vcmpgtsb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb
+
+  res_vbc = vec_vcmpgtub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub
+
+  res_vbs = vec_vcmpgtsh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh
+
+  res_vbs = vec_vcmpgtuh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh
+
+  res_vbi = vec_vcmpgtsw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw
+
+  res_vbi = vec_vcmpgtuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw
+
+  res_vbi = vec_vcmpgtfp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp
 
   /* vec_cmple */
-  res_vbi = vec_cmple(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp
+  res_vbi = vec_cmple(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp
 }
 
 // CHECK-LABEL: define void @test6
 void test6() {
   /* vec_cmplt */
-  res_vbc = vec_cmplt(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpgtsb
-  res_vbc = vec_cmplt(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpgtub
-  res_vbs = vec_cmplt(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh
-  res_vbs = vec_cmplt(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpgtuh
-  res_vbi = vec_cmplt(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw
-  res_vbi = vec_cmplt(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpgtuw
-  res_vbi = vec_cmplt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp
+  res_vbc = vec_cmplt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb
+
+  res_vbc = vec_cmplt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub
+
+  res_vbs = vec_cmplt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh
+
+  res_vbs = vec_cmplt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh
+
+  res_vbi = vec_cmplt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw
+
+  res_vbi = vec_cmplt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw
+
+  res_vbi = vec_cmplt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp
 
   /* vec_ctf */
-  res_vf  = vec_ctf(vi, param_i);               // CHECK: @llvm.ppc.altivec.vcfsx
-  res_vf  = vec_ctf(vui, 0);                    // CHECK: @llvm.ppc.altivec.vcfux
-  res_vf  = vec_vcfsx(vi, 0);                   // CHECK: @llvm.ppc.altivec.vcfsx
-  res_vf  = vec_vcfux(vui, 0);                  // CHECK: @llvm.ppc.altivec.vcfux
+  res_vf  = vec_ctf(vi, param_i);
+// CHECK: @llvm.ppc.altivec.vcfsx
+// CHECK-LE: @llvm.ppc.altivec.vcfsx
+
+  res_vf  = vec_ctf(vui, 0);
+// CHECK: @llvm.ppc.altivec.vcfux
+// CHECK-LE: @llvm.ppc.altivec.vcfux
+
+  res_vf  = vec_vcfsx(vi, 0);
+// CHECK: @llvm.ppc.altivec.vcfsx
+// CHECK-LE: @llvm.ppc.altivec.vcfsx
+
+  res_vf  = vec_vcfux(vui, 0);
+// CHECK: @llvm.ppc.altivec.vcfux
+// CHECK-LE: @llvm.ppc.altivec.vcfux
 
   /* vec_cts */
-  res_vi = vec_cts(vf, 0);                      // CHECK: @llvm.ppc.altivec.vctsxs
-  res_vi = vec_vctsxs(vf, 0);                   // CHECK: @llvm.ppc.altivec.vctsxs
+  res_vi = vec_cts(vf, 0);
+// CHECK: @llvm.ppc.altivec.vctsxs
+// CHECK-LE: @llvm.ppc.altivec.vctsxs
+
+  res_vi = vec_vctsxs(vf, 0);
+// CHECK: @llvm.ppc.altivec.vctsxs
+// CHECK-LE: @llvm.ppc.altivec.vctsxs
 
   /* vec_ctu */
-  res_vui = vec_ctu(vf, 0);                     // CHECK: @llvm.ppc.altivec.vctuxs
-  res_vui = vec_vctuxs(vf, 0);                  // CHECK: @llvm.ppc.altivec.vctuxs
+  res_vui = vec_ctu(vf, 0);
+// CHECK: @llvm.ppc.altivec.vctuxs
+// CHECK-LE: @llvm.ppc.altivec.vctuxs
+
+  res_vui = vec_vctuxs(vf, 0);
+// CHECK: @llvm.ppc.altivec.vctuxs
+// CHECK-LE: @llvm.ppc.altivec.vctuxs
 
   /* vec_dss */
-  vec_dss(param_i);                             // CHECK: @llvm.ppc.altivec.dss
+  vec_dss(param_i);
+// CHECK: @llvm.ppc.altivec.dss
+// CHECK-LE: @llvm.ppc.altivec.dss
 
   /* vec_dssall */
-  vec_dssall();                                 // CHECK: @llvm.ppc.altivec.dssall
+  vec_dssall();
+// CHECK: @llvm.ppc.altivec.dssall
+// CHECK-LE: @llvm.ppc.altivec.dssall
 
   /* vec_dst */
-  vec_dst(&vsc, 0, 0);                          // CHECK: @llvm.ppc.altivec.dst
+  vec_dst(&vsc, 0, 0);
+// CHECK: @llvm.ppc.altivec.dst
+// CHECK-LE: @llvm.ppc.altivec.dst
 
   /* vec_dstst */
-  vec_dstst(&vs, 0, 0);                         // CHECK: @llvm.ppc.altivec.dstst
+  vec_dstst(&vs, 0, 0);
+// CHECK: @llvm.ppc.altivec.dstst
+// CHECK-LE: @llvm.ppc.altivec.dstst
 
   /* vec_dststt */
-  vec_dststt(&param_i, 0, 0);                   // CHECK: @llvm.ppc.altivec.dststt
+  vec_dststt(&param_i, 0, 0);
+// CHECK: @llvm.ppc.altivec.dststt
+// CHECK-LE: @llvm.ppc.altivec.dststt
 
   /* vec_dstt */
-  vec_dstt(&vf, 0, 0);                          // CHECK: @llvm.ppc.altivec.dstt
+  vec_dstt(&vf, 0, 0);
+// CHECK: @llvm.ppc.altivec.dstt
+// CHECK-LE: @llvm.ppc.altivec.dstt
 
   /* vec_expte */
-  res_vf = vec_expte(vf);                       // CHECK: @llvm.ppc.altivec.vexptefp
-  res_vf = vec_vexptefp(vf);                    // CHECK: @llvm.ppc.altivec.vexptefp
+  res_vf = vec_expte(vf);
+// CHECK: @llvm.ppc.altivec.vexptefp
+// CHECK-LE: @llvm.ppc.altivec.vexptefp
+
+  res_vf = vec_vexptefp(vf);
+// CHECK: @llvm.ppc.altivec.vexptefp
+// CHECK-LE: @llvm.ppc.altivec.vexptefp
 
   /* vec_floor */
-  res_vf = vec_floor(vf);                       // CHECK: @llvm.ppc.altivec.vrfim
-  res_vf = vec_vrfim(vf);                       // CHECK: @llvm.ppc.altivec.vrfim
+  res_vf = vec_floor(vf);
+// CHECK: @llvm.ppc.altivec.vrfim
+// CHECK-LE: @llvm.ppc.altivec.vrfim
+
+  res_vf = vec_vrfim(vf);
+// CHECK: @llvm.ppc.altivec.vrfim
+// CHECK-LE: @llvm.ppc.altivec.vrfim
 
   /* vec_ld */
-  res_vsc = vec_ld(0, &vsc);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vsc = vec_ld(0, &param_sc);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vuc = vec_ld(0, &vuc);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vuc = vec_ld(0, &param_uc);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vbc = vec_ld(0, &vbc);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vs  = vec_ld(0, &vs);                     // CHECK: @llvm.ppc.altivec.lvx
-  res_vs  = vec_ld(0, &param_s);                // CHECK: @llvm.ppc.altivec.lvx
-  res_vus = vec_ld(0, &vus);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vus = vec_ld(0, &param_us);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vbs = vec_ld(0, &vbs);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vp  = vec_ld(0, &vp);                     // CHECK: @llvm.ppc.altivec.lvx
-  res_vi  = vec_ld(0, &vi);                     // CHECK: @llvm.ppc.altivec.lvx
-  res_vi  = vec_ld(0, &param_i);                // CHECK: @llvm.ppc.altivec.lvx
-  res_vui = vec_ld(0, &vui);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vui = vec_ld(0, &param_ui);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vbi = vec_ld(0, &vbi);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vf  = vec_ld(0, &vf);                     // CHECK: @llvm.ppc.altivec.lvx
-  res_vf  = vec_ld(0, &param_f);                // CHECK: @llvm.ppc.altivec.lvx
-  res_vsc = vec_lvx(0, &vsc);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vsc = vec_lvx(0, &param_sc);              // CHECK: @llvm.ppc.altivec.lvx
-  res_vuc = vec_lvx(0, &vuc);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vuc = vec_lvx(0, &param_uc);              // CHECK: @llvm.ppc.altivec.lvx
-  res_vbc = vec_lvx(0, &vbc);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vs  = vec_lvx(0, &vs);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vs  = vec_lvx(0, &param_s);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vus = vec_lvx(0, &vus);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vus = vec_lvx(0, &param_us);              // CHECK: @llvm.ppc.altivec.lvx
-  res_vbs = vec_lvx(0, &vbs);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vp  = vec_lvx(0, &vp);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vi  = vec_lvx(0, &vi);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vi  = vec_lvx(0, &param_i);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vui = vec_lvx(0, &vui);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vui = vec_lvx(0, &param_ui);              // CHECK: @llvm.ppc.altivec.lvx
-  res_vbi = vec_lvx(0, &vbi);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vf  = vec_lvx(0, &vf);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vf  = vec_lvx(0, &param_f);               // CHECK: @llvm.ppc.altivec.lvx
+  res_vsc = vec_ld(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vsc = vec_ld(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vuc = vec_ld(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vuc = vec_ld(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbc = vec_ld(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vs  = vec_ld(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vs  = vec_ld(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vus = vec_ld(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vus = vec_ld(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbs = vec_ld(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vp  = vec_ld(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vi  = vec_ld(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vi  = vec_ld(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vui = vec_ld(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vui = vec_ld(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbi = vec_ld(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vf  = vec_ld(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vf  = vec_ld(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vsc = vec_lvx(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vsc = vec_lvx(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vuc = vec_lvx(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vuc = vec_lvx(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbc = vec_lvx(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vs  = vec_lvx(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vs  = vec_lvx(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vus = vec_lvx(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vus = vec_lvx(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbs = vec_lvx(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vp  = vec_lvx(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vi  = vec_lvx(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vi  = vec_lvx(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vui = vec_lvx(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vui = vec_lvx(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbi = vec_lvx(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vf  = vec_lvx(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vf  = vec_lvx(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
 
   /* vec_lde */
-  res_vsc = vec_lde(0, &param_sc);              // CHECK: @llvm.ppc.altivec.lvebx
-  res_vuc = vec_lde(0, &param_uc);              // CHECK: @llvm.ppc.altivec.lvebx
-  res_vs  = vec_lde(0, &param_s);               // CHECK: @llvm.ppc.altivec.lvehx
-  res_vus = vec_lde(0, &param_us);              // CHECK: @llvm.ppc.altivec.lvehx
-  res_vi  = vec_lde(0, &param_i);               // CHECK: @llvm.ppc.altivec.lvewx
-  res_vui = vec_lde(0, &param_ui);              // CHECK: @llvm.ppc.altivec.lvewx
-  res_vf  = vec_lde(0, &param_f);               // CHECK: @llvm.ppc.altivec.lvewx
-  res_vsc = vec_lvebx(0, &param_sc);            // CHECK: @llvm.ppc.altivec.lvebx
-  res_vuc = vec_lvebx(0, &param_uc);            // CHECK: @llvm.ppc.altivec.lvebx
-  res_vs  = vec_lvehx(0, &param_s);             // CHECK: @llvm.ppc.altivec.lvehx
-  res_vus = vec_lvehx(0, &param_us);            // CHECK: @llvm.ppc.altivec.lvehx
-  res_vi  = vec_lvewx(0, &param_i);             // CHECK: @llvm.ppc.altivec.lvewx
-  res_vui = vec_lvewx(0, &param_ui);            // CHECK: @llvm.ppc.altivec.lvewx
-  res_vf  = vec_lvewx(0, &param_f);             // CHECK: @llvm.ppc.altivec.lvewx
+  res_vsc = vec_lde(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvebx
+// CHECK-LE: @llvm.ppc.altivec.lvebx
+
+  res_vuc = vec_lde(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvebx
+// CHECK-LE: @llvm.ppc.altivec.lvebx
+
+  res_vs  = vec_lde(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvehx
+// CHECK-LE: @llvm.ppc.altivec.lvehx
+
+  res_vus = vec_lde(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvehx
+// CHECK-LE: @llvm.ppc.altivec.lvehx
+
+  res_vi  = vec_lde(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vui = vec_lde(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vf  = vec_lde(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vsc = vec_lvebx(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvebx
+// CHECK-LE: @llvm.ppc.altivec.lvebx
+
+  res_vuc = vec_lvebx(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvebx
+// CHECK-LE: @llvm.ppc.altivec.lvebx
+
+  res_vs  = vec_lvehx(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvehx
+// CHECK-LE: @llvm.ppc.altivec.lvehx
+
+  res_vus = vec_lvehx(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvehx
+// CHECK-LE: @llvm.ppc.altivec.lvehx
+
+  res_vi  = vec_lvewx(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vui = vec_lvewx(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vf  = vec_lvewx(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
 
   /* vec_ldl */
-  res_vsc = vec_ldl(0, &vsc);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vsc = vec_ldl(0, &param_sc);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vuc = vec_ldl(0, &vuc);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vuc = vec_ldl(0, &param_uc);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbc = vec_ldl(0, &vbc);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vs  = vec_ldl(0, &vs);                    // CHECK: @llvm.ppc.altivec.lvxl
-  res_vs  = vec_ldl(0, &param_s);               // CHECK: @llvm.ppc.altivec.lvxl
-  res_vus = vec_ldl(0, &vus);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vus = vec_ldl(0, &param_us);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbs = vec_ldl(0, &vbs);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vp  = vec_ldl(0, &vp);                    // CHECK: @llvm.ppc.altivec.lvxl
-  res_vi  = vec_ldl(0, &vi);                    // CHECK: @llvm.ppc.altivec.lvxl
-  res_vi  = vec_ldl(0, &param_i);               // CHECK: @llvm.ppc.altivec.lvxl
-  res_vui = vec_ldl(0, &vui);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vui = vec_ldl(0, &param_ui);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbi = vec_ldl(0, &vbi);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vf  = vec_ldl(0, &vf);                    // CHECK: @llvm.ppc.altivec.lvxl
-  res_vf  = vec_ldl(0, &param_f);               // CHECK: @llvm.ppc.altivec.lvxl
-  res_vsc = vec_lvxl(0, &vsc);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vsc = vec_lvxl(0, &param_sc);             // CHECK: @llvm.ppc.altivec.lvxl
-  res_vuc = vec_lvxl(0, &vuc);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbc = vec_lvxl(0, &vbc);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vuc = vec_lvxl(0, &param_uc);             // CHECK: @llvm.ppc.altivec.lvxl
-  res_vs  = vec_lvxl(0, &vs);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vs  = vec_lvxl(0, &param_s);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vus = vec_lvxl(0, &vus);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vus = vec_lvxl(0, &param_us);             // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbs = vec_lvxl(0, &vbs);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vp  = vec_lvxl(0, &vp);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vi  = vec_lvxl(0, &vi);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vi  = vec_lvxl(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vui = vec_lvxl(0, &vui);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vui = vec_lvxl(0, &param_ui);             // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbi = vec_lvxl(0, &vbi);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vf  = vec_lvxl(0, &vf);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vf  = vec_lvxl(0, &param_f);              // CHECK: @llvm.ppc.altivec.lvxl
+  res_vsc = vec_ldl(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vsc = vec_ldl(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vuc = vec_ldl(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vuc = vec_ldl(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbc = vec_ldl(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vs  = vec_ldl(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vs  = vec_ldl(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vus = vec_ldl(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vus = vec_ldl(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbs = vec_ldl(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vp  = vec_ldl(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vi  = vec_ldl(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vi  = vec_ldl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vui = vec_ldl(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vui = vec_ldl(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbi = vec_ldl(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vf  = vec_ldl(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vf  = vec_ldl(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vsc = vec_lvxl(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vsc = vec_lvxl(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vuc = vec_lvxl(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbc = vec_lvxl(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vuc = vec_lvxl(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vs  = vec_lvxl(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vs  = vec_lvxl(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vus = vec_lvxl(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vus = vec_lvxl(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbs = vec_lvxl(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vp  = vec_lvxl(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vi  = vec_lvxl(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vi  = vec_lvxl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vui = vec_lvxl(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vui = vec_lvxl(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbi = vec_lvxl(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vf  = vec_lvxl(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vf  = vec_lvxl(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
 
   /* vec_loge */
-  res_vf = vec_loge(vf);                        // CHECK: @llvm.ppc.altivec.vlogefp
-  res_vf = vec_vlogefp(vf);                     // CHECK: @llvm.ppc.altivec.vlogefp
+  res_vf = vec_loge(vf);
+// CHECK: @llvm.ppc.altivec.vlogefp
+// CHECK-LE: @llvm.ppc.altivec.vlogefp
+
+  res_vf = vec_vlogefp(vf);
+// CHECK: @llvm.ppc.altivec.vlogefp
+// CHECK-LE: @llvm.ppc.altivec.vlogefp
 
   /* vec_lvsl */
-  res_vuc = vec_lvsl(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvsl
+  res_vuc = vec_lvsl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
 
   /* vec_lvsr */
-  res_vuc = vec_lvsr(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvsr
+  res_vuc = vec_lvsr(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.lvsr
 
   /* vec_madd */
-  res_vf =vec_madd(vf, vf, vf);                 // CHECK: @llvm.ppc.altivec.vmaddfp
-  res_vf = vec_vmaddfp(vf, vf, vf);             // CHECK: @llvm.ppc.altivec.vmaddfp
+  res_vf =vec_madd(vf, vf, vf);
+// CHECK: @llvm.ppc.altivec.vmaddfp
+// CHECK-LE: @llvm.ppc.altivec.vmaddfp
+
+  res_vf = vec_vmaddfp(vf, vf, vf);
+// CHECK: @llvm.ppc.altivec.vmaddfp
+// CHECK-LE: @llvm.ppc.altivec.vmaddfp
 
   /* vec_madds */
-  res_vs = vec_madds(vs, vs, vs);               // CHECK: @llvm.ppc.altivec.vmhaddshs
-  res_vs = vec_vmhaddshs(vs, vs, vs);           // CHECK: @llvm.ppc.altivec.vmhaddshs
+  res_vs = vec_madds(vs, vs, vs);
+// CHECK: @llvm.ppc.altivec.vmhaddshs
+// CHECK-LE: @llvm.ppc.altivec.vmhaddshs
+
+  res_vs = vec_vmhaddshs(vs, vs, vs);
+// CHECK: @llvm.ppc.altivec.vmhaddshs
+// CHECK-LE: @llvm.ppc.altivec.vmhaddshs
 
   /* vec_max */
-  res_vsc = vec_max(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vsc = vec_max(vbc, vsc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vsc = vec_max(vsc, vbc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vuc = vec_max(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vuc = vec_max(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vuc = vec_max(vuc, vbc);                  // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vs  = vec_max(vs, vs);                    // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vs  = vec_max(vbs, vs);                   // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vs  = vec_max(vs, vbs);                   // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vus = vec_max(vus, vus);                  // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vus = vec_max(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vus = vec_max(vus, vbs);                  // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vi  = vec_max(vi, vi);                    // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vi  = vec_max(vbi, vi);                   // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vi  = vec_max(vi, vbi);                   // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vui = vec_max(vui, vui);                  // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vui = vec_max(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vui = vec_max(vui, vbi);                  // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vf  = vec_max(vf, vf);                    // CHECK: @llvm.ppc.altivec.vmaxfp
-  res_vsc = vec_vmaxsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vsc = vec_vmaxsb(vbc, vsc);               // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vsc = vec_vmaxsb(vsc, vbc);               // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vuc = vec_vmaxub(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vuc = vec_vmaxub(vbc, vuc);               // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vuc = vec_vmaxub(vuc, vbc);               // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vs  = vec_vmaxsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vs  = vec_vmaxsh(vbs, vs);                // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vs  = vec_vmaxsh(vs, vbs);                // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vus = vec_vmaxuh(vus, vus);               // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vus = vec_vmaxuh(vbs, vus);               // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vus = vec_vmaxuh(vus, vbs);               // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vi  = vec_vmaxsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vi  = vec_vmaxsw(vbi, vi);                // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vi  = vec_vmaxsw(vi, vbi);                // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vui = vec_vmaxuw(vui, vui);               // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vui = vec_vmaxuw(vbi, vui);               // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vui = vec_vmaxuw(vui, vbi);               // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vf  = vec_vmaxfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vmaxfp
+  res_vsc = vec_max(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vsc = vec_max(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vsc = vec_max(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vuc = vec_max(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vuc = vec_max(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vuc = vec_max(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vs  = vec_max(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vs  = vec_max(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vs  = vec_max(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vus = vec_max(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vus = vec_max(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vus = vec_max(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vi  = vec_max(vi, vi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vi  = vec_max(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vi  = vec_max(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vui = vec_max(vui, vui);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vui = vec_max(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vui = vec_max(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vf  = vec_max(vf, vf);
+// CHECK: @llvm.ppc.altivec.vmaxfp
+// CHECK-LE: @llvm.ppc.altivec.vmaxfp
+
+  res_vsc = vec_vmaxsb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vsc = vec_vmaxsb(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vsc = vec_vmaxsb(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vuc = vec_vmaxub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vuc = vec_vmaxub(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vuc = vec_vmaxub(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vs  = vec_vmaxsh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vs  = vec_vmaxsh(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vs  = vec_vmaxsh(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vus = vec_vmaxuh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vus = vec_vmaxuh(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vus = vec_vmaxuh(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vi  = vec_vmaxsw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vi  = vec_vmaxsw(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vi  = vec_vmaxsw(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vui = vec_vmaxuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vui = vec_vmaxuw(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vui = vec_vmaxuw(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vf  = vec_vmaxfp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vmaxfp
+// CHECK-LE: @llvm.ppc.altivec.vmaxfp
 
   /* vec_mergeh */
-  res_vsc = vec_mergeh(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_mergeh(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_mergeh(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_mergeh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_mergeh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_mergeh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_mergeh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_mergeh(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_mergeh(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_mergeh(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_mergeh(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vmrghb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vmrghb(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vmrghb(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vmrghh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vmrghh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vmrghh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vmrghh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vmrghw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vmrghw(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_vmrghw(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vmrghw(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_mergeh(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_mergeh(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_mergeh(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_mergeh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_mergeh(vp, vp);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_mergeh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_mergeh(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_mergeh(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_mergeh(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_mergeh(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_mergeh(vf, vf);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vmrghb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vmrghb(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vmrghb(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vmrghh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vmrghh(vp, vp);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vmrghh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vmrghh(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vmrghw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vmrghw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_vmrghw(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vmrghw(vf, vf);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_mergel */
-  res_vsc = vec_mergel(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_mergel(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_mergel(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_mergel(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_mergeh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_mergel(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_mergel(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_mergel(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_mergel(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_mergel(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_mergel(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vmrglb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vmrglb(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vmrglb(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vmrglh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vmrglh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vmrglh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vmrglh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vmrglw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vmrglw(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_vmrglw(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vmrglw(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_mergel(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_mergel(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_mergel(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_mergel(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_mergeh(vp, vp);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_mergel(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_mergel(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_mergel(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_mergel(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_mergel(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_mergel(vf, vf);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vmrglb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vmrglb(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vmrglb(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vmrglh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vmrglh(vp, vp);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vmrglh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vmrglh(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vmrglw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vmrglw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_vmrglw(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vmrglw(vf, vf);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_mfvscr */
-  vus = vec_mfvscr();                           // CHECK: @llvm.ppc.altivec.mfvscr
+  vus = vec_mfvscr();
+// CHECK: @llvm.ppc.altivec.mfvscr
+// CHECK-LE: @llvm.ppc.altivec.mfvscr
 
   /* vec_min */
-  res_vsc = vec_min(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vminsb
-  res_vsc = vec_min(vbc, vsc);                  // CHECK: @llvm.ppc.altivec.vminsb
-  res_vsc = vec_min(vsc, vbc);                  // CHECK: @llvm.ppc.altivec.vminsb
-  res_vuc = vec_min(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vminub
-  res_vuc = vec_min(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vminub
-  res_vuc = vec_min(vuc, vbc);                  // CHECK: @llvm.ppc.altivec.vminub
-  res_vs  = vec_min(vs, vs);                    // CHECK: @llvm.ppc.altivec.vminsh
-  res_vs  = vec_min(vbs, vs);                   // CHECK: @llvm.ppc.altivec.vminsh
-  res_vs  = vec_min(vs, vbs);                   // CHECK: @llvm.ppc.altivec.vminsh
-  res_vus = vec_min(vus, vus);                  // CHECK: @llvm.ppc.altivec.vminuh
-  res_vus = vec_min(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vminuh
-  res_vus = vec_min(vus, vbs);                  // CHECK: @llvm.ppc.altivec.vminuh
-  res_vi  = vec_min(vi, vi);                    // CHECK: @llvm.ppc.altivec.vminsw
-  res_vi  = vec_min(vbi, vi);                   // CHECK: @llvm.ppc.altivec.vminsw
-  res_vi  = vec_min(vi, vbi);                   // CHECK: @llvm.ppc.altivec.vminsw
-  res_vui = vec_min(vui, vui);                  // CHECK: @llvm.ppc.altivec.vminuw
-  res_vui = vec_min(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vminuw
-  res_vui = vec_min(vui, vbi);                  // CHECK: @llvm.ppc.altivec.vminuw
-  res_vf  = vec_min(vf, vf);                    // CHECK: @llvm.ppc.altivec.vminfp
-  res_vsc = vec_vminsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vminsb
-  res_vsc = vec_vminsb(vbc, vsc);               // CHECK: @llvm.ppc.altivec.vminsb
-  res_vsc = vec_vminsb(vsc, vbc);               // CHECK: @llvm.ppc.altivec.vminsb
-  res_vuc = vec_vminub(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vminub
-  res_vuc = vec_vminub(vbc, vuc);               // CHECK: @llvm.ppc.altivec.vminub
-  res_vuc = vec_vminub(vuc, vbc);               // CHECK: @llvm.ppc.altivec.vminub
-  res_vs  = vec_vminsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vminsh
-  res_vs  = vec_vminsh(vbs, vs);                // CHECK: @llvm.ppc.altivec.vminsh
-  res_vs  = vec_vminsh(vs, vbs);                // CHECK: @llvm.ppc.altivec.vminsh
-  res_vus = vec_vminuh(vus, vus);               // CHECK: @llvm.ppc.altivec.vminuh
-  res_vus = vec_vminuh(vbs, vus);               // CHECK: @llvm.ppc.altivec.vminuh
-  res_vus = vec_vminuh(vus, vbs);               // CHECK: @llvm.ppc.altivec.vminuh
-  res_vi  = vec_vminsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vminsw
-  res_vi  = vec_vminsw(vbi, vi);                // CHECK: @llvm.ppc.altivec.vminsw
-  res_vi  = vec_vminsw(vi, vbi);                // CHECK: @llvm.ppc.altivec.vminsw
-  res_vui = vec_vminuw(vui, vui);               // CHECK: @llvm.ppc.altivec.vminuw
-  res_vui = vec_vminuw(vbi, vui);               // CHECK: @llvm.ppc.altivec.vminuw
-  res_vui = vec_vminuw(vui, vbi);               // CHECK: @llvm.ppc.altivec.vminuw
-  res_vf  = vec_vminfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vminfp
+  res_vsc = vec_min(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vsc = vec_min(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vsc = vec_min(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vuc = vec_min(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vuc = vec_min(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vuc = vec_min(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vs  = vec_min(vs, vs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vs  = vec_min(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vs  = vec_min(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vus = vec_min(vus, vus);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vus = vec_min(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vus = vec_min(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vi  = vec_min(vi, vi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vi  = vec_min(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vi  = vec_min(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vui = vec_min(vui, vui);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vui = vec_min(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vui = vec_min(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vf  = vec_min(vf, vf);
+// CHECK: @llvm.ppc.altivec.vminfp
+// CHECK-LE: @llvm.ppc.altivec.vminfp
+
+  res_vsc = vec_vminsb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vsc = vec_vminsb(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vsc = vec_vminsb(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vuc = vec_vminub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vuc = vec_vminub(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vuc = vec_vminub(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vs  = vec_vminsh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vs  = vec_vminsh(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vs  = vec_vminsh(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vus = vec_vminuh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vus = vec_vminuh(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vus = vec_vminuh(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vi  = vec_vminsw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vi  = vec_vminsw(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vi  = vec_vminsw(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vui = vec_vminuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vui = vec_vminuw(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vui = vec_vminuw(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vf  = vec_vminfp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vminfp
+// CHECK-LE: @llvm.ppc.altivec.vminfp
 
   /* vec_mladd */
-  res_vus = vec_mladd(vus, vus, vus);           // CHECK: mul <8 x i16>
-                                                // CHECK: add <8 x i16>
+  res_vus = vec_mladd(vus, vus, vus);
+// CHECK: mul <8 x i16>
+// CHECK: add <8 x i16>
+// CHECK-LE: mul <8 x i16>
+// CHECK-LE: add <8 x i16>
 
-  res_vs = vec_mladd(vus, vs, vs);              // CHECK: mul <8 x i16>
-                                                // CHECK: add <8 x i16>
+  res_vs = vec_mladd(vus, vs, vs);
+// CHECK: mul <8 x i16>
+// CHECK: add <8 x i16>
+// CHECK-LE: mul <8 x i16>
+// CHECK-LE: add <8 x i16>
 
-  res_vs = vec_mladd(vs, vus, vus);             // CHECK: mul <8 x i16>
-                                                // CHECK: add <8 x i16>
+  res_vs = vec_mladd(vs, vus, vus);
+// CHECK: mul <8 x i16>
+// CHECK: add <8 x i16>
+// CHECK-LE: mul <8 x i16>
+// CHECK-LE: add <8 x i16>
 
-  res_vs = vec_mladd(vs, vs, vs);               // CHECK: mul <8 x i16>
-                                                // CHECK: add <8 x i16>
+  res_vs = vec_mladd(vs, vs, vs);
+// CHECK: mul <8 x i16>
+// CHECK: add <8 x i16>
+// CHECK-LE: mul <8 x i16>
+// CHECK-LE: add <8 x i16>
 
   /* vec_mradds */
-  res_vs = vec_mradds(vs, vs, vs);              // CHECK: @llvm.ppc.altivec.vmhraddshs
-  res_vs = vec_vmhraddshs(vs, vs, vs);          // CHECK: @llvm.ppc.altivec.vmhraddshs
- 
+  res_vs = vec_mradds(vs, vs, vs);
+// CHECK: @llvm.ppc.altivec.vmhraddshs
+// CHECK-LE: @llvm.ppc.altivec.vmhraddshs
+
+  res_vs = vec_vmhraddshs(vs, vs, vs);
+// CHECK: @llvm.ppc.altivec.vmhraddshs
+// CHECK-LE: @llvm.ppc.altivec.vmhraddshs
+
   /* vec_msum */
-  res_vi  = vec_msum(vsc, vuc, vi);             // CHECK: @llvm.ppc.altivec.vmsummbm
-  res_vui = vec_msum(vuc, vuc, vui);            // CHECK: @llvm.ppc.altivec.vmsumubm
-  res_vi  = vec_msum(vs, vs, vi);               // CHECK: @llvm.ppc.altivec.vmsumshm
-  res_vui = vec_msum(vus, vus, vui);            // CHECK: @llvm.ppc.altivec.vmsumuhm
-  res_vi  = vec_vmsummbm(vsc, vuc, vi);         // CHECK: @llvm.ppc.altivec.vmsummbm
-  res_vui = vec_vmsumubm(vuc, vuc, vui);        // CHECK: @llvm.ppc.altivec.vmsumubm
-  res_vi  = vec_vmsumshm(vs, vs, vi);           // CHECK: @llvm.ppc.altivec.vmsumshm
-  res_vui = vec_vmsumuhm(vus, vus, vui);        // CHECK: @llvm.ppc.altivec.vmsumuhm
+  res_vi  = vec_msum(vsc, vuc, vi);
+// CHECK: @llvm.ppc.altivec.vmsummbm
+// CHECK-LE: @llvm.ppc.altivec.vmsummbm
+
+  res_vui = vec_msum(vuc, vuc, vui);
+// CHECK: @llvm.ppc.altivec.vmsumubm
+// CHECK-LE: @llvm.ppc.altivec.vmsumubm
+
+  res_vi  = vec_msum(vs, vs, vi);
+// CHECK: @llvm.ppc.altivec.vmsumshm
+// CHECK-LE: @llvm.ppc.altivec.vmsumshm
+
+  res_vui = vec_msum(vus, vus, vui);
+// CHECK: @llvm.ppc.altivec.vmsumuhm
+// CHECK-LE: @llvm.ppc.altivec.vmsumuhm
+
+  res_vi  = vec_vmsummbm(vsc, vuc, vi);
+// CHECK: @llvm.ppc.altivec.vmsummbm
+// CHECK-LE: @llvm.ppc.altivec.vmsummbm
+
+  res_vui = vec_vmsumubm(vuc, vuc, vui);
+// CHECK: @llvm.ppc.altivec.vmsumubm
+// CHECK-LE: @llvm.ppc.altivec.vmsumubm
+
+  res_vi  = vec_vmsumshm(vs, vs, vi);
+// CHECK: @llvm.ppc.altivec.vmsumshm
+// CHECK-LE: @llvm.ppc.altivec.vmsumshm
+
+  res_vui = vec_vmsumuhm(vus, vus, vui);
+// CHECK: @llvm.ppc.altivec.vmsumuhm
+// CHECK-LE: @llvm.ppc.altivec.vmsumuhm
 
   /* vec_msums */
-  res_vi  = vec_msums(vs, vs, vi);              // CHECK: @llvm.ppc.altivec.vmsumshs
-  res_vui = vec_msums(vus, vus, vui);           // CHECK: @llvm.ppc.altivec.vmsumuhs
-  res_vi  = vec_vmsumshs(vs, vs, vi);           // CHECK: @llvm.ppc.altivec.vmsumshs
-  res_vui = vec_vmsumuhs(vus, vus, vui);        // CHECK: @llvm.ppc.altivec.vmsumuhs
+  res_vi  = vec_msums(vs, vs, vi);
+// CHECK: @llvm.ppc.altivec.vmsumshs
+// CHECK-LE: @llvm.ppc.altivec.vmsumshs
+
+  res_vui = vec_msums(vus, vus, vui);
+// CHECK: @llvm.ppc.altivec.vmsumuhs
+// CHECK-LE: @llvm.ppc.altivec.vmsumuhs
+
+  res_vi  = vec_vmsumshs(vs, vs, vi);
+// CHECK: @llvm.ppc.altivec.vmsumshs
+// CHECK-LE: @llvm.ppc.altivec.vmsumshs
+
+  res_vui = vec_vmsumuhs(vus, vus, vui);
+// CHECK: @llvm.ppc.altivec.vmsumuhs
+// CHECK-LE: @llvm.ppc.altivec.vmsumuhs
 
   /* vec_mtvscr */
-  vec_mtvscr(vsc);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vuc);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vbc);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vs);                               // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vus);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vbs);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vp);                               // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vi);                               // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vui);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vbi);                              // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vsc);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vuc);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vbc);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vs);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vus);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vbs);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vp);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vi);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vui);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vbi);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
 
   /* vec_mule */
-  res_vs  = vec_mule(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vmulesb
-  res_vus = vec_mule(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vmuleub
-  res_vi  = vec_mule(vs, vs);                   // CHECK: @llvm.ppc.altivec.vmulesh
-  res_vui = vec_mule(vus, vus);                 // CHECK: @llvm.ppc.altivec.vmuleuh
-  res_vs  = vec_vmulesb(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vmulesb
-  res_vus = vec_vmuleub(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vmuleub
-  res_vi  = vec_vmulesh(vs, vs);                // CHECK: @llvm.ppc.altivec.vmulesh
-  res_vui = vec_vmuleuh(vus, vus);              // CHECK: @llvm.ppc.altivec.vmuleuh
+  res_vs  = vec_mule(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmulesb
+// CHECK-LE: @llvm.ppc.altivec.vmulosb
+
+  res_vus = vec_mule(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmuleub
+// CHECK-LE: @llvm.ppc.altivec.vmuloub
+
+  res_vi  = vec_mule(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmulesh
+// CHECK-LE: @llvm.ppc.altivec.vmulosh
+
+  res_vui = vec_mule(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmuleuh
+// CHECK-LE: @llvm.ppc.altivec.vmulouh
+
+  res_vs  = vec_vmulesb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmulesb
+// CHECK-LE: @llvm.ppc.altivec.vmulosb
+
+  res_vus = vec_vmuleub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmuleub
+// CHECK-LE: @llvm.ppc.altivec.vmuloub
+
+  res_vi  = vec_vmulesh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmulesh
+// CHECK-LE: @llvm.ppc.altivec.vmulosh
+
+  res_vui = vec_vmuleuh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmuleuh
+// CHECK-LE: @llvm.ppc.altivec.vmulouh
 
   /* vec_mulo */
-  res_vs  = vec_mulo(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vmulosb
-  res_vus = vec_mulo(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vmuloub
-  res_vi  = vec_mulo(vs, vs);                   // CHECK: @llvm.ppc.altivec.vmulosh
-  res_vui = vec_mulo(vus, vus);                 // CHECK: @llvm.ppc.altivec.vmulouh
-  res_vs  = vec_vmulosb(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vmulosb
-  res_vus = vec_vmuloub(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vmuloub
-  res_vi  = vec_vmulosh(vs, vs);                // CHECK: @llvm.ppc.altivec.vmulosh
-  res_vui = vec_vmulouh(vus, vus);              // CHECK: @llvm.ppc.altivec.vmulouh
+  res_vs  = vec_mulo(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmulosb
+// CHECK-LE: @llvm.ppc.altivec.vmulesb
+
+  res_vus = vec_mulo(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmuloub
+// CHECK-LE: @llvm.ppc.altivec.vmuleub
+
+  res_vi  = vec_mulo(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmulosh
+// CHECK-LE: @llvm.ppc.altivec.vmulesh
+
+  res_vui = vec_mulo(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmulouh
+// CHECK-LE: @llvm.ppc.altivec.vmuleuh
+
+  res_vs  = vec_vmulosb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmulosb
+// CHECK-LE: @llvm.ppc.altivec.vmulesb
+
+  res_vus = vec_vmuloub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmuloub
+// CHECK-LE: @llvm.ppc.altivec.vmuleub
+
+  res_vi  = vec_vmulosh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmulosh
+// CHECK-LE: @llvm.ppc.altivec.vmulesh
+
+  res_vui = vec_vmulouh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmulouh
+// CHECK-LE: @llvm.ppc.altivec.vmuleuh
 
   /* vec_nmsub */
-  res_vf = vec_nmsub(vf, vf, vf);               // CHECK: @llvm.ppc.altivec.vnmsubfp
-  res_vf = vec_vnmsubfp(vf, vf, vf);            // CHECK: @llvm.ppc.altivec.vnmsubfp
+  res_vf = vec_nmsub(vf, vf, vf);
+// CHECK: @llvm.ppc.altivec.vnmsubfp
+// CHECK-LE: @llvm.ppc.altivec.vnmsubfp
+
+  res_vf = vec_vnmsubfp(vf, vf, vf);
+// CHECK: @llvm.ppc.altivec.vnmsubfp
+// CHECK-LE: @llvm.ppc.altivec.vnmsubfp
 
   /* vec_nor */
-  res_vsc = vec_nor(vsc, vsc);                  // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vsc = vec_nor(vsc, vsc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vuc = vec_nor(vuc, vuc);                  // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vuc = vec_nor(vuc, vuc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vuc = vec_nor(vbc, vbc);                  // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vuc = vec_nor(vbc, vbc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vs  = vec_nor(vs, vs);                    // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vs  = vec_nor(vs, vs);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vus = vec_nor(vus, vus);                  // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vus = vec_nor(vus, vus);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vus = vec_nor(vbs, vbs);                  // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vus = vec_nor(vbs, vbs);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vi  = vec_nor(vi, vi);                    // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vi  = vec_nor(vi, vi);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vui = vec_nor(vui, vui);                  // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vui = vec_nor(vui, vui);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vui = vec_nor(vbi, vbi);                  // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vui = vec_nor(vbi, vbi);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vf  = vec_nor(vf, vf);                    // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vf  = vec_nor(vf, vf);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vsc = vec_vnor(vsc, vsc);                 // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vsc = vec_vnor(vsc, vsc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vuc = vec_vnor(vuc, vuc);                 // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vuc = vec_vnor(vuc, vuc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vuc = vec_vnor(vbc, vbc);                 // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vuc = vec_vnor(vbc, vbc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vs  = vec_vnor(vs, vs);                   // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vs  = vec_vnor(vs, vs);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vus = vec_vnor(vus, vus);                 // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vus = vec_vnor(vus, vus);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vus = vec_vnor(vbs, vbs);                 // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vus = vec_vnor(vbs, vbs);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vi  = vec_vnor(vi, vi);                   // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vi  = vec_vnor(vi, vi);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vui = vec_vnor(vui, vui);                 // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vui = vec_vnor(vui, vui);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vui = vec_vnor(vbi, vbi);                 // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vui = vec_vnor(vbi, vbi);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vf  = vec_vnor(vf, vf);                   // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vf  = vec_vnor(vf, vf);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
   /* vec_or */
-  res_vsc = vec_or(vsc, vsc);                   // CHECK: or <16 x i8>
-  res_vsc = vec_or(vbc, vsc);                   // CHECK: or <16 x i8>
-  res_vsc = vec_or(vsc, vbc);                   // CHECK: or <16 x i8>
-  res_vuc = vec_or(vuc, vuc);                   // CHECK: or <16 x i8>
-  res_vuc = vec_or(vbc, vuc);                   // CHECK: or <16 x i8>
-  res_vuc = vec_or(vuc, vbc);                   // CHECK: or <16 x i8>
-  res_vbc = vec_or(vbc, vbc);                   // CHECK: or <16 x i8>
-  res_vs  = vec_or(vs, vs);                     // CHECK: or <8 x i16>
-  res_vs  = vec_or(vbs, vs);                    // CHECK: or <8 x i16>
-  res_vs  = vec_or(vs, vbs);                    // CHECK: or <8 x i16>
-  res_vus = vec_or(vus, vus);                   // CHECK: or <8 x i16>
-  res_vus = vec_or(vbs, vus);                   // CHECK: or <8 x i16>
-  res_vus = vec_or(vus, vbs);                   // CHECK: or <8 x i16>
-  res_vbs = vec_or(vbs, vbs);                   // CHECK: or <8 x i16>
-  res_vi  = vec_or(vi, vi);                     // CHECK: or <4 x i32>
-  res_vi  = vec_or(vbi, vi);                    // CHECK: or <4 x i32>
-  res_vi  = vec_or(vi, vbi);                    // CHECK: or <4 x i32>
-  res_vui = vec_or(vui, vui);                   // CHECK: or <4 x i32>
-  res_vui = vec_or(vbi, vui);                   // CHECK: or <4 x i32>
-  res_vui = vec_or(vui, vbi);                   // CHECK: or <4 x i32>
-  res_vbi = vec_or(vbi, vbi);                   // CHECK: or <4 x i32>
-  res_vf  = vec_or(vf, vf);                     // CHECK: or <4 x i32>
-  res_vf  = vec_or(vbi, vf);                    // CHECK: or <4 x i32>
-  res_vf  = vec_or(vf, vbi);                    // CHECK: or <4 x i32>
-  res_vsc = vec_vor(vsc, vsc);                  // CHECK: or <16 x i8>
-  res_vsc = vec_vor(vbc, vsc);                  // CHECK: or <16 x i8>
-  res_vsc = vec_vor(vsc, vbc);                  // CHECK: or <16 x i8>
-  res_vuc = vec_vor(vuc, vuc);                  // CHECK: or <16 x i8>
-  res_vuc = vec_vor(vbc, vuc);                  // CHECK: or <16 x i8>
-  res_vuc = vec_vor(vuc, vbc);                  // CHECK: or <16 x i8>
-  res_vbc = vec_vor(vbc, vbc);                  // CHECK: or <16 x i8>
-  res_vs  = vec_vor(vs, vs);                    // CHECK: or <8 x i16>
-  res_vs  = vec_vor(vbs, vs);                   // CHECK: or <8 x i16>
-  res_vs  = vec_vor(vs, vbs);                   // CHECK: or <8 x i16>
-  res_vus = vec_vor(vus, vus);                  // CHECK: or <8 x i16>
-  res_vus = vec_vor(vbs, vus);                  // CHECK: or <8 x i16>
-  res_vus = vec_vor(vus, vbs);                  // CHECK: or <8 x i16>
-  res_vbs = vec_vor(vbs, vbs);                  // CHECK: or <8 x i16>
-  res_vi  = vec_vor(vi, vi);                    // CHECK: or <4 x i32>
-  res_vi  = vec_vor(vbi, vi);                   // CHECK: or <4 x i32>
-  res_vi  = vec_vor(vi, vbi);                   // CHECK: or <4 x i32>
-  res_vui = vec_vor(vui, vui);                  // CHECK: or <4 x i32>
-  res_vui = vec_vor(vbi, vui);                  // CHECK: or <4 x i32>
-  res_vui = vec_vor(vui, vbi);                  // CHECK: or <4 x i32>
-  res_vbi = vec_vor(vbi, vbi);                  // CHECK: or <4 x i32>
-  res_vf  = vec_vor(vf, vf);                    // CHECK: or <4 x i32>
-  res_vf  = vec_vor(vbi, vf);                   // CHECK: or <4 x i32>
-  res_vf  = vec_vor(vf, vbi);                   // CHECK: or <4 x i32>
+  res_vsc = vec_or(vsc, vsc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vsc = vec_or(vbc, vsc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vsc = vec_or(vsc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_or(vuc, vuc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_or(vbc, vuc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_or(vuc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vbc = vec_or(vbc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vs  = vec_or(vs, vs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vs  = vec_or(vbs, vs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vs  = vec_or(vs, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_or(vus, vus);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_or(vbs, vus);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_or(vus, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vbs = vec_or(vbs, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vi  = vec_or(vi, vi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vi  = vec_or(vbi, vi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vi  = vec_or(vi, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_or(vui, vui);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_or(vbi, vui);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_or(vui, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vbi = vec_or(vbi, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_or(vf, vf);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_or(vbi, vf);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_or(vf, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vsc = vec_vor(vsc, vsc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vsc = vec_vor(vbc, vsc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vsc = vec_vor(vsc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_vor(vuc, vuc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_vor(vbc, vuc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_vor(vuc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vbc = vec_vor(vbc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vs  = vec_vor(vs, vs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vs  = vec_vor(vbs, vs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vs  = vec_vor(vs, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_vor(vus, vus);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_vor(vbs, vus);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_vor(vus, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vbs = vec_vor(vbs, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vi  = vec_vor(vi, vi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vi  = vec_vor(vbi, vi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vi  = vec_vor(vi, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_vor(vui, vui);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_vor(vbi, vui);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_vor(vui, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vbi = vec_vor(vbi, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_vor(vf, vf);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_vor(vbi, vf);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_vor(vf, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
 
   /* vec_pack */
-  res_vsc = vec_pack(vs, vs);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_pack(vus, vus);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_pack(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_pack(vi, vi);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_pack(vui, vui);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_pack(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vpkuhum(vs, vs);                // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vpkuhum(vus, vus);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vpkuhum(vbs, vbs);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vpkuwum(vi, vi);                // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vpkuwum(vui, vui);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vpkuwum(vbi, vbi);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_pack(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_pack(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_pack(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_pack(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_pack(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_pack(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vpkuhum(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vpkuhum(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vpkuhum(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vpkuwum(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vpkuwum(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vpkuwum(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_packpx */
-  res_vp = vec_packpx(vui, vui);                // CHECK: @llvm.ppc.altivec.vpkpx
-  res_vp = vec_vpkpx(vui, vui);                 // CHECK: @llvm.ppc.altivec.vpkpx
+  res_vp = vec_packpx(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkpx
+// CHECK-LE: @llvm.ppc.altivec.vpkpx
+
+  res_vp = vec_vpkpx(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkpx
+// CHECK-LE: @llvm.ppc.altivec.vpkpx
 
   /* vec_packs */
-  res_vsc = vec_packs(vs, vs);                  // CHECK: @llvm.ppc.altivec.vpkshss
-  res_vuc = vec_packs(vus, vus);                // CHECK: @llvm.ppc.altivec.vpkuhus
-  res_vs  = vec_packs(vi, vi);                  // CHECK: @llvm.ppc.altivec.vpkswss
-  res_vus = vec_packs(vui, vui);                // CHECK: @llvm.ppc.altivec.vpkuwus
-  res_vsc = vec_vpkshss(vs, vs);                // CHECK: @llvm.ppc.altivec.vpkshss
-  res_vuc = vec_vpkuhus(vus, vus);              // CHECK: @llvm.ppc.altivec.vpkuhus
-  res_vs  = vec_vpkswss(vi, vi);                // CHECK: @llvm.ppc.altivec.vpkswss
-  res_vus = vec_vpkuwus(vui, vui);              // CHECK: @llvm.ppc.altivec.vpkuwus
+  res_vsc = vec_packs(vs, vs);
+// CHECK: @llvm.ppc.altivec.vpkshss
+// CHECK-LE: @llvm.ppc.altivec.vpkshss
+
+  res_vuc = vec_packs(vus, vus);
+// CHECK: @llvm.ppc.altivec.vpkuhus
+// CHECK-LE: @llvm.ppc.altivec.vpkuhus
+
+  res_vs  = vec_packs(vi, vi);
+// CHECK: @llvm.ppc.altivec.vpkswss
+// CHECK-LE: @llvm.ppc.altivec.vpkswss
+
+  res_vus = vec_packs(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkuwus
+// CHECK-LE: @llvm.ppc.altivec.vpkuwus
+
+  res_vsc = vec_vpkshss(vs, vs);
+// CHECK: @llvm.ppc.altivec.vpkshss
+// CHECK-LE: @llvm.ppc.altivec.vpkshss
+
+  res_vuc = vec_vpkuhus(vus, vus);
+// CHECK: @llvm.ppc.altivec.vpkuhus
+// CHECK-LE: @llvm.ppc.altivec.vpkuhus
+
+  res_vs  = vec_vpkswss(vi, vi);
+// CHECK: @llvm.ppc.altivec.vpkswss
+// CHECK-LE: @llvm.ppc.altivec.vpkswss
+
+  res_vus = vec_vpkuwus(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkuwus
+// CHECK-LE: @llvm.ppc.altivec.vpkuwus
 
   /* vec_packsu */
-  res_vuc = vec_packsu(vs, vs);                 // CHECK: @llvm.ppc.altivec.vpkshus
-  res_vuc = vec_packsu(vus, vus);               // CHECK: @llvm.ppc.altivec.vpkuhus
-  res_vus = vec_packsu(vi, vi);                 // CHECK: @llvm.ppc.altivec.vpkswus
-  res_vus = vec_packsu(vui, vui);               // CHECK: @llvm.ppc.altivec.vpkuwus
-  res_vuc = vec_vpkshus(vs, vs);                // CHECK: @llvm.ppc.altivec.vpkshus
-  res_vuc = vec_vpkshus(vus, vus);              // CHECK: @llvm.ppc.altivec.vpkuhus
-  res_vus = vec_vpkswus(vi, vi);                // CHECK: @llvm.ppc.altivec.vpkswus
-  res_vus = vec_vpkswus(vui, vui);              // CHECK: @llvm.ppc.altivec.vpkuwus
+  res_vuc = vec_packsu(vs, vs);
+// CHECK: @llvm.ppc.altivec.vpkshus
+// CHECK-LE: @llvm.ppc.altivec.vpkshus
+
+  res_vuc = vec_packsu(vus, vus);
+// CHECK: @llvm.ppc.altivec.vpkuhus
+// CHECK-LE: @llvm.ppc.altivec.vpkuhus
+
+  res_vus = vec_packsu(vi, vi);
+// CHECK: @llvm.ppc.altivec.vpkswus
+// CHECK-LE: @llvm.ppc.altivec.vpkswus
+
+  res_vus = vec_packsu(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkuwus
+// CHECK-LE: @llvm.ppc.altivec.vpkuwus
+
+  res_vuc = vec_vpkshus(vs, vs);
+// CHECK: @llvm.ppc.altivec.vpkshus
+// CHECK-LE: @llvm.ppc.altivec.vpkshus
+
+  res_vuc = vec_vpkshus(vus, vus);
+// CHECK: @llvm.ppc.altivec.vpkuhus
+// CHECK-LE: @llvm.ppc.altivec.vpkuhus
+
+  res_vus = vec_vpkswus(vi, vi);
+// CHECK: @llvm.ppc.altivec.vpkswus
+// CHECK-LE: @llvm.ppc.altivec.vpkswus
+
+  res_vus = vec_vpkswus(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkuwus
+// CHECK-LE: @llvm.ppc.altivec.vpkuwus
 
   /* vec_perm */
-  res_vsc = vec_perm(vsc, vsc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_perm(vuc, vuc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_perm(vbc, vbc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_perm(vs, vs, vuc);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_perm(vus, vus, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_perm(vbs, vbs, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_perm(vp, vp, vuc);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_perm(vi, vi, vuc);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_perm(vui, vui, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_perm(vbi, vbi, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_perm(vf, vf, vuc);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vperm(vsc, vsc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vperm(vuc, vuc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vperm(vbc, vbc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vperm(vs, vs, vuc);             // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vperm(vus, vus, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vperm(vbs, vbs, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vperm(vp, vp, vuc);             // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vperm(vi, vi, vuc);             // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vperm(vui, vui, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_vperm(vbi, vbi, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vperm(vf, vf, vuc);             // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_perm(vsc, vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_perm(vuc, vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_perm(vbc, vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_perm(vs, vs, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_perm(vus, vus, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_perm(vbs, vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_perm(vp, vp, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_perm(vi, vi, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_perm(vui, vui, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_perm(vbi, vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_perm(vf, vf, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vperm(vsc, vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vperm(vuc, vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vperm(vbc, vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vperm(vs, vs, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vperm(vus, vus, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vperm(vbs, vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vperm(vp, vp, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vperm(vi, vi, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vperm(vui, vui, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_vperm(vbi, vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vperm(vf, vf, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_re */
-  res_vf = vec_re(vf);                          // CHECK: @llvm.ppc.altivec.vrefp
-  res_vf = vec_vrefp(vf);                       // CHECK: @llvm.ppc.altivec.vrefp
+  res_vf = vec_re(vf);
+// CHECK: @llvm.ppc.altivec.vrefp
+// CHECK-LE: @llvm.ppc.altivec.vrefp
+
+  res_vf = vec_vrefp(vf);
+// CHECK: @llvm.ppc.altivec.vrefp
+// CHECK-LE: @llvm.ppc.altivec.vrefp
 
   /* vec_rl */
-  res_vsc = vec_rl(vsc, vuc);                   // CHECK: @llvm.ppc.altivec.vrlb
-  res_vuc = vec_rl(vuc, vuc);                   // CHECK: @llvm.ppc.altivec.vrlb
-  res_vs  = vec_rl(vs, vus);                    // CHECK: @llvm.ppc.altivec.vrlh
-  res_vus = vec_rl(vus, vus);                   // CHECK: @llvm.ppc.altivec.vrlh
-  res_vi  = vec_rl(vi, vui);                    // CHECK: @llvm.ppc.altivec.vrlw
-  res_vui = vec_rl(vui, vui);                   // CHECK: @llvm.ppc.altivec.vrlw
-  res_vsc = vec_vrlb(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vrlb
-  res_vuc = vec_vrlb(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vrlb
-  res_vs  = vec_vrlh(vs, vus);                  // CHECK: @llvm.ppc.altivec.vrlh
-  res_vus = vec_vrlh(vus, vus);                 // CHECK: @llvm.ppc.altivec.vrlh
-  res_vi  = vec_vrlw(vi, vui);                  // CHECK: @llvm.ppc.altivec.vrlw
-  res_vui = vec_vrlw(vui, vui);                 // CHECK: @llvm.ppc.altivec.vrlw
+  res_vsc = vec_rl(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vrlb
+// CHECK-LE: @llvm.ppc.altivec.vrlb
+
+  res_vuc = vec_rl(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vrlb
+// CHECK-LE: @llvm.ppc.altivec.vrlb
+
+  res_vs  = vec_rl(vs, vus);
+// CHECK: @llvm.ppc.altivec.vrlh
+// CHECK-LE: @llvm.ppc.altivec.vrlh
+
+  res_vus = vec_rl(vus, vus);
+// CHECK: @llvm.ppc.altivec.vrlh
+// CHECK-LE: @llvm.ppc.altivec.vrlh
+
+  res_vi  = vec_rl(vi, vui);
+// CHECK: @llvm.ppc.altivec.vrlw
+// CHECK-LE: @llvm.ppc.altivec.vrlw
+
+  res_vui = vec_rl(vui, vui);
+// CHECK: @llvm.ppc.altivec.vrlw
+// CHECK-LE: @llvm.ppc.altivec.vrlw
+
+  res_vsc = vec_vrlb(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vrlb
+// CHECK-LE: @llvm.ppc.altivec.vrlb
+
+  res_vuc = vec_vrlb(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vrlb
+// CHECK-LE: @llvm.ppc.altivec.vrlb
+
+  res_vs  = vec_vrlh(vs, vus);
+// CHECK: @llvm.ppc.altivec.vrlh
+// CHECK-LE: @llvm.ppc.altivec.vrlh
+
+  res_vus = vec_vrlh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vrlh
+// CHECK-LE: @llvm.ppc.altivec.vrlh
+
+  res_vi  = vec_vrlw(vi, vui);
+// CHECK: @llvm.ppc.altivec.vrlw
+// CHECK-LE: @llvm.ppc.altivec.vrlw
+
+  res_vui = vec_vrlw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vrlw
+// CHECK-LE: @llvm.ppc.altivec.vrlw
 
   /* vec_round */
-  res_vf = vec_round(vf);                       // CHECK: @llvm.ppc.altivec.vrfin
-  res_vf = vec_vrfin(vf);                       // CHECK: @llvm.ppc.altivec.vrfin
+  res_vf = vec_round(vf);
+// CHECK: @llvm.ppc.altivec.vrfin
+// CHECK-LE: @llvm.ppc.altivec.vrfin
+
+  res_vf = vec_vrfin(vf);
+// CHECK: @llvm.ppc.altivec.vrfin
+// CHECK-LE: @llvm.ppc.altivec.vrfin
 
   /* vec_rsqrte */
-  res_vf = vec_rsqrte(vf);                      // CHECK: @llvm.ppc.altivec.vrsqrtefp
-  res_vf = vec_vrsqrtefp(vf);                   // CHECK: @llvm.ppc.altivec.vrsqrtefp
+  res_vf = vec_rsqrte(vf);
+// CHECK: @llvm.ppc.altivec.vrsqrtefp
+// CHECK-LE: @llvm.ppc.altivec.vrsqrtefp
+
+  res_vf = vec_vrsqrtefp(vf);
+// CHECK: @llvm.ppc.altivec.vrsqrtefp
+// CHECK-LE: @llvm.ppc.altivec.vrsqrtefp
 
   /* vec_sel */
-  res_vsc = vec_sel(vsc, vsc, vuc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vsc = vec_sel(vsc, vsc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vsc = vec_sel(vsc, vsc, vbc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vsc = vec_sel(vsc, vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vuc = vec_sel(vuc, vuc, vuc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vuc = vec_sel(vuc, vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vuc = vec_sel(vuc, vuc, vbc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vuc = vec_sel(vuc, vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vbc = vec_sel(vbc, vbc, vuc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vbc = vec_sel(vbc, vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vbc = vec_sel(vbc, vbc, vbc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vbc = vec_sel(vbc, vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vs  = vec_sel(vs, vs, vus);               // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vs  = vec_sel(vs, vs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vs  = vec_sel(vs, vs, vbs);               // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vs  = vec_sel(vs, vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vus = vec_sel(vus, vus, vus);             // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vus = vec_sel(vus, vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vus = vec_sel(vus, vus, vbs);             // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vus = vec_sel(vus, vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vbs = vec_sel(vbs, vbs, vus);             // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vbs = vec_sel(vbs, vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vbs = vec_sel(vbs, vbs, vbs);             // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vbs = vec_sel(vbs, vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vi  = vec_sel(vi, vi, vui);               // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vi  = vec_sel(vi, vi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vi  = vec_sel(vi, vi, vbi);               // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vi  = vec_sel(vi, vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vui = vec_sel(vui, vui, vui);             // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vui = vec_sel(vui, vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vui = vec_sel(vui, vui, vbi);             // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vui = vec_sel(vui, vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vbi = vec_sel(vbi, vbi, vui);             // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vbi = vec_sel(vbi, vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vbi = vec_sel(vbi, vbi, vbi);             // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vbi = vec_sel(vbi, vbi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vf  = vec_sel(vf, vf, vui);               // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vf  = vec_sel(vf, vf, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vf  = vec_sel(vf, vf, vbi);               // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vf  = vec_sel(vf, vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vsc = vec_vsel(vsc, vsc, vuc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vsc = vec_vsel(vsc, vsc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vsc = vec_vsel(vsc, vsc, vbc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vsc = vec_vsel(vsc, vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vuc = vec_vsel(vuc, vuc, vuc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vuc = vec_vsel(vuc, vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vuc = vec_vsel(vuc, vuc, vbc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vuc = vec_vsel(vuc, vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vbc = vec_vsel(vbc, vbc, vuc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vbc = vec_vsel(vbc, vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vbc = vec_vsel(vbc, vbc, vbc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vbc = vec_vsel(vbc, vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vs  = vec_vsel(vs, vs, vus);              // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vs  = vec_vsel(vs, vs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vs  = vec_vsel(vs, vs, vbs);              // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vs  = vec_vsel(vs, vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vus = vec_vsel(vus, vus, vus);            // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vus = vec_vsel(vus, vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vus = vec_vsel(vus, vus, vbs);            // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vus = vec_vsel(vus, vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vbs = vec_vsel(vbs, vbs, vus);            // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vbs = vec_vsel(vbs, vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vbs = vec_vsel(vbs, vbs, vbs);            // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vbs = vec_vsel(vbs, vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vi  = vec_vsel(vi, vi, vui);              // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vi  = vec_vsel(vi, vi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vi  = vec_vsel(vi, vi, vbi);              // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vi  = vec_vsel(vi, vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vui = vec_vsel(vui, vui, vui);            // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vui = vec_vsel(vui, vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vui = vec_vsel(vui, vui, vbi);            // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vui = vec_vsel(vui, vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vbi = vec_vsel(vbi, vbi, vui);            // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vbi = vec_vsel(vbi, vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vbi = vec_vsel(vbi, vbi, vbi);            // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vbi = vec_vsel(vbi, vbi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vf  = vec_vsel(vf, vf, vui);              // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vf  = vec_vsel(vf, vf, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vf  = vec_vsel(vf, vf, vbi);              // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vf  = vec_vsel(vf, vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
   /* vec_sl */
-  res_vsc = vec_sl(vsc, vuc);                   // CHECK: shl <16 x i8>
-  res_vuc = vec_sl(vuc, vuc);                   // CHECK: shl <16 x i8>
-  res_vs  = vec_sl(vs, vus);                    // CHECK: shl <8 x i16>
-  res_vus = vec_sl(vus, vus);                   // CHECK: shl <8 x i16>
-  res_vi  = vec_sl(vi, vui);                    // CHECK: shl <4 x i32>
-  res_vui = vec_sl(vui, vui);                   // CHECK: shl <4 x i32>
-  res_vsc = vec_vslb(vsc, vuc);                 // CHECK: shl <16 x i8>
-  res_vuc = vec_vslb(vuc, vuc);                 // CHECK: shl <16 x i8>
-  res_vs  = vec_vslh(vs, vus);                  // CHECK: shl <8 x i16>
-  res_vus = vec_vslh(vus, vus);                 // CHECK: shl <8 x i16>
-  res_vi  = vec_vslw(vi, vui);                  // CHECK: shl <4 x i32>
-  res_vui = vec_vslw(vui, vui);                 // CHECK: shl <4 x i32>
+  res_vsc = vec_sl(vsc, vuc);
+// CHECK: shl <16 x i8>
+// CHECK-LE: shl <16 x i8>
+
+  res_vuc = vec_sl(vuc, vuc);
+// CHECK: shl <16 x i8>
+// CHECK-LE: shl <16 x i8>
+
+  res_vs  = vec_sl(vs, vus);
+// CHECK: shl <8 x i16>
+// CHECK-LE: shl <8 x i16>
+
+  res_vus = vec_sl(vus, vus);
+// CHECK: shl <8 x i16>
+// CHECK-LE: shl <8 x i16>
+
+  res_vi  = vec_sl(vi, vui);
+// CHECK: shl <4 x i32>
+// CHECK-LE: shl <4 x i32>
+
+  res_vui = vec_sl(vui, vui);
+// CHECK: shl <4 x i32>
+// CHECK-LE: shl <4 x i32>
+
+  res_vsc = vec_vslb(vsc, vuc);
+// CHECK: shl <16 x i8>
+// CHECK-LE: shl <16 x i8>
+
+  res_vuc = vec_vslb(vuc, vuc);
+// CHECK: shl <16 x i8>
+// CHECK-LE: shl <16 x i8>
+
+  res_vs  = vec_vslh(vs, vus);
+// CHECK: shl <8 x i16>
+// CHECK-LE: shl <8 x i16>
+
+  res_vus = vec_vslh(vus, vus);
+// CHECK: shl <8 x i16>
+// CHECK-LE: shl <8 x i16>
+
+  res_vi  = vec_vslw(vi, vui);
+// CHECK: shl <4 x i32>
+// CHECK-LE: shl <4 x i32>
+
+  res_vui = vec_vslw(vui, vui);
+// CHECK: shl <4 x i32>
+// CHECK-LE: shl <4 x i32>
 
   /* vec_sld */
-  res_vsc = vec_sld(vsc, vsc, 0);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_sld(vuc, vuc, 0);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_sld(vs, vs, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_sld(vus, vus, 0);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_sld(vp, vp, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_sld(vi, vi, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_sld(vui, vui, 0);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_sld(vf, vf, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vsldoi(vsc, vsc, 0);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vsldoi(vuc, vuc, 0);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vsldoi(vs, vs, 0);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vsldoi(vus, vus, 0);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vsldoi(vp, vp, 0);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vsldoi(vi, vi, 0);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vsldoi(vui, vui, 0);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vsldoi(vf, vf, 0);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_sld(vsc, vsc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_sld(vuc, vuc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_sld(vs, vs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_sld(vus, vus, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_sld(vp, vp, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_sld(vi, vi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_sld(vui, vui, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_sld(vf, vf, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vsldoi(vsc, vsc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vsldoi(vuc, vuc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vsldoi(vs, vs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vsldoi(vus, vus, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vsldoi(vp, vp, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vsldoi(vi, vi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vsldoi(vui, vui, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vsldoi(vf, vf, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 1
+// CHECK-LE: sub nsw i32 {{[%_.a-z0-9]+}}, 15
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_sll */
-  res_vsc = vec_sll(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_sll(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_sll(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_sll(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_sll(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_sll(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_sll(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_sll(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_sll(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_sll(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_sll(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_sll(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_sll(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_sll(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_sll(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_sll(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_sll(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_sll(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_sll(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_sll(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_sll(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_sll(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_sll(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_sll(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_sll(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_sll(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_sll(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_sll(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_sll(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_sll(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_vsl(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_vsl(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_vsl(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_vsl(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_vsl(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_vsl(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_vsl(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_vsl(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_vsl(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_vsl(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_vsl(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_vsl(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_vsl(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_vsl(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_vsl(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_vsl(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_vsl(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_vsl(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_vsl(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_vsl(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_vsl(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_vsl(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_vsl(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_vsl(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_vsl(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_vsl(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_vsl(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_vsl(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_vsl(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_vsl(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vsc = vec_sll(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_sll(vsc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_sll(vsc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_sll(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_sll(vuc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_sll(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_sll(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_sll(vbc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_sll(vbc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_sll(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_sll(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_sll(vs, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_sll(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_sll(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_sll(vus, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_sll(vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_sll(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_sll(vbs, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_sll(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_sll(vp, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_sll(vp, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_sll(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_sll(vi, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_sll(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_sll(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_sll(vui, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_sll(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_sll(vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_sll(vbi, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_sll(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_vsl(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_vsl(vsc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_vsl(vsc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_vsl(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_vsl(vuc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_vsl(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_vsl(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_vsl(vbc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_vsl(vbc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_vsl(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_vsl(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_vsl(vs, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_vsl(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_vsl(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_vsl(vus, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_vsl(vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_vsl(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_vsl(vbs, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_vsl(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_vsl(vp, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_vsl(vp, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_vsl(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_vsl(vi, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_vsl(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_vsl(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_vsl(vui, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_vsl(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_vsl(vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_vsl(vbi, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_vsl(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
 
   /* vec_slo */
-  res_vsc = vec_slo(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vsc = vec_slo(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vuc = vec_slo(vuc, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vuc = vec_slo(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vs  = vec_slo(vs, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vs  = vec_slo(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vus = vec_slo(vus, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vus = vec_slo(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vp  = vec_slo(vp, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vp  = vec_slo(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vi  = vec_slo(vi, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vi  = vec_slo(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vui = vec_slo(vui, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vui = vec_slo(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vf  = vec_slo(vf, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vf  = vec_slo(vf, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vsc = vec_vslo(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vsc = vec_vslo(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vuc = vec_vslo(vuc, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vuc = vec_vslo(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vs  = vec_vslo(vs, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vs  = vec_vslo(vs, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vus = vec_vslo(vus, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vus = vec_vslo(vus, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vp  = vec_vslo(vp, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vp  = vec_vslo(vp, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vi  = vec_vslo(vi, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vi  = vec_vslo(vi, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vui = vec_vslo(vui, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vui = vec_vslo(vui, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vf  = vec_vslo(vf, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vf  = vec_vslo(vf, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vsc = vec_slo(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vsc = vec_slo(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vuc = vec_slo(vuc, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vuc = vec_slo(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vs  = vec_slo(vs, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vs  = vec_slo(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vus = vec_slo(vus, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vus = vec_slo(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vp  = vec_slo(vp, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vp  = vec_slo(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vi  = vec_slo(vi, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vi  = vec_slo(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vui = vec_slo(vui, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vui = vec_slo(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vf  = vec_slo(vf, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vf  = vec_slo(vf, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vsc = vec_vslo(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vsc = vec_vslo(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vuc = vec_vslo(vuc, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vuc = vec_vslo(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vs  = vec_vslo(vs, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vs  = vec_vslo(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vus = vec_vslo(vus, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vus = vec_vslo(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vp  = vec_vslo(vp, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vp  = vec_vslo(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vi  = vec_vslo(vi, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vi  = vec_vslo(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vui = vec_vslo(vui, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vui = vec_vslo(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vf  = vec_vslo(vf, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vf  = vec_vslo(vf, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
 
   /* vec_splat */
-  res_vsc = vec_splat(vsc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_splat(vuc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_splat(vbc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_splat(vs, 0);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_splat(vus, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_splat(vbs, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_splat(vp, 0);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_splat(vi, 0);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_splat(vui, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_splat(vbi, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_splat(vf, 0);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vspltb(vsc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vspltb(vuc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vspltb(vbc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vsplth(vs, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vsplth(vus, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vsplth(vbs, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vsplth(vp, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vspltw(vi, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vspltw(vui, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_vspltw(vbi, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vspltw(vf, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_splat(vsc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_splat(vuc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_splat(vbc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_splat(vs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_splat(vus, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_splat(vbs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_splat(vp, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_splat(vi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_splat(vui, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_splat(vbi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_splat(vf, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vspltb(vsc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vspltb(vuc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vspltb(vbc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vsplth(vs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vsplth(vus, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vsplth(vbs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vsplth(vp, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vspltw(vi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vspltw(vui, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_vspltw(vbi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vspltw(vf, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_splat_s8 */
   res_vsc = vec_splat_s8(0x09);                 // TODO: add check
@@ -1329,1729 +3833,4717 @@
   res_vui = vec_splat_u32(0x09);                // TODO: add check
 
   /* vec_sr */
-  res_vsc = vec_sr(vsc, vuc);                   // CHECK: shr <16 x i8>
-  res_vuc = vec_sr(vuc, vuc);                   // CHECK: shr <16 x i8>
-  res_vs  = vec_sr(vs, vus);                    // CHECK: shr <8 x i16>
-  res_vus = vec_sr(vus, vus);                   // CHECK: shr <8 x i16>
-  res_vi  = vec_sr(vi, vui);                    // CHECK: shr <4 x i32>
-  res_vui = vec_sr(vui, vui);                   // CHECK: shr <4 x i32>
-  res_vsc = vec_vsrb(vsc, vuc);                 // CHECK: shr <16 x i8>
-  res_vuc = vec_vsrb(vuc, vuc);                 // CHECK: shr <16 x i8>
-  res_vs  = vec_vsrh(vs, vus);                  // CHECK: shr <8 x i16>
-  res_vus = vec_vsrh(vus, vus);                 // CHECK: shr <8 x i16>
-  res_vi  = vec_vsrw(vi, vui);                  // CHECK: shr <4 x i32>
-  res_vui = vec_vsrw(vui, vui);                 // CHECK: shr <4 x i32>
+  res_vsc = vec_sr(vsc, vuc);
+// CHECK: shr <16 x i8>
+// CHECK-LE: shr <16 x i8>
+
+  res_vuc = vec_sr(vuc, vuc);
+// CHECK: shr <16 x i8>
+// CHECK-LE: shr <16 x i8>
+
+  res_vs  = vec_sr(vs, vus);
+// CHECK: shr <8 x i16>
+// CHECK-LE: shr <8 x i16>
+
+  res_vus = vec_sr(vus, vus);
+// CHECK: shr <8 x i16>
+// CHECK-LE: shr <8 x i16>
+
+  res_vi  = vec_sr(vi, vui);
+// CHECK: shr <4 x i32>
+// CHECK-LE: shr <4 x i32>
+
+  res_vui = vec_sr(vui, vui);
+// CHECK: shr <4 x i32>
+// CHECK-LE: shr <4 x i32>
+
+  res_vsc = vec_vsrb(vsc, vuc);
+// CHECK: shr <16 x i8>
+// CHECK-LE: shr <16 x i8>
+
+  res_vuc = vec_vsrb(vuc, vuc);
+// CHECK: shr <16 x i8>
+// CHECK-LE: shr <16 x i8>
+
+  res_vs  = vec_vsrh(vs, vus);
+// CHECK: shr <8 x i16>
+// CHECK-LE: shr <8 x i16>
+
+  res_vus = vec_vsrh(vus, vus);
+// CHECK: shr <8 x i16>
+// CHECK-LE: shr <8 x i16>
+
+  res_vi  = vec_vsrw(vi, vui);
+// CHECK: shr <4 x i32>
+// CHECK-LE: shr <4 x i32>
+
+  res_vui = vec_vsrw(vui, vui);
+// CHECK: shr <4 x i32>
+// CHECK-LE: shr <4 x i32>
 
   /* vec_sra */
-  res_vsc = vec_sra(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsrab
-  res_vuc = vec_sra(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsrab
-  res_vs  = vec_sra(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsrah
-  res_vus = vec_sra(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsrah
-  res_vi  = vec_sra(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsraw
-  res_vui = vec_sra(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsraw
-  res_vsc = vec_vsrab(vsc, vuc);                // CHECK: @llvm.ppc.altivec.vsrab
-  res_vuc = vec_vsrab(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vsrab
-  res_vs  = vec_vsrah(vs, vus);                 // CHECK: @llvm.ppc.altivec.vsrah
-  res_vus = vec_vsrah(vus, vus);                // CHECK: @llvm.ppc.altivec.vsrah
-  res_vi  = vec_vsraw(vi, vui);                 // CHECK: @llvm.ppc.altivec.vsraw
-  res_vui = vec_vsraw(vui, vui);                // CHECK: @llvm.ppc.altivec.vsraw
+  res_vsc = vec_sra(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsrab
+// CHECK-LE: @llvm.ppc.altivec.vsrab
+
+  res_vuc = vec_sra(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsrab
+// CHECK-LE: @llvm.ppc.altivec.vsrab
+
+  res_vs  = vec_sra(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsrah
+// CHECK-LE: @llvm.ppc.altivec.vsrah
+
+  res_vus = vec_sra(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsrah
+// CHECK-LE: @llvm.ppc.altivec.vsrah
+
+  res_vi  = vec_sra(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsraw
+// CHECK-LE: @llvm.ppc.altivec.vsraw
+
+  res_vui = vec_sra(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsraw
+// CHECK-LE: @llvm.ppc.altivec.vsraw
+
+  res_vsc = vec_vsrab(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsrab
+// CHECK-LE: @llvm.ppc.altivec.vsrab
+
+  res_vuc = vec_vsrab(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsrab
+// CHECK-LE: @llvm.ppc.altivec.vsrab
+
+  res_vs  = vec_vsrah(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsrah
+// CHECK-LE: @llvm.ppc.altivec.vsrah
+
+  res_vus = vec_vsrah(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsrah
+// CHECK-LE: @llvm.ppc.altivec.vsrah
+
+  res_vi  = vec_vsraw(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsraw
+// CHECK-LE: @llvm.ppc.altivec.vsraw
+
+  res_vui = vec_vsraw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsraw
+// CHECK-LE: @llvm.ppc.altivec.vsraw
 
   /* vec_srl */
-  res_vsc = vec_srl(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_srl(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_srl(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_srl(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_srl(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_srl(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_srl(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_srl(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_srl(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_srl(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_srl(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_srl(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_srl(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_srl(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_srl(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_srl(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_srl(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_srl(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_srl(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_srl(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_srl(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_srl(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_srl(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_srl(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_srl(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_srl(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_srl(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_srl(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_srl(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_srl(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_vsr(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_vsr(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_vsr(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_vsr(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_vsr(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_vsr(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_vsr(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_vsr(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_vsr(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_vsr(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_vsr(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_vsr(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_vsr(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_vsr(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_vsr(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_vsr(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_vsr(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_vsr(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_vsr(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_vsr(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_vsr(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_vsr(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_vsr(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_vsr(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_vsr(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_vsr(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_vsr(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_vsr(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_vsr(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_vsr(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vsc = vec_srl(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_srl(vsc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_srl(vsc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_srl(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_srl(vuc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_srl(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_srl(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_srl(vbc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_srl(vbc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_srl(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_srl(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_srl(vs, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_srl(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_srl(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_srl(vus, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_srl(vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_srl(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_srl(vbs, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_srl(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_srl(vp, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_srl(vp, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_srl(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_srl(vi, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_srl(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_srl(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_srl(vui, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_srl(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_srl(vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_srl(vbi, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_srl(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_vsr(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_vsr(vsc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_vsr(vsc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_vsr(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_vsr(vuc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_vsr(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_vsr(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_vsr(vbc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_vsr(vbc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_vsr(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_vsr(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_vsr(vs, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_vsr(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_vsr(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_vsr(vus, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_vsr(vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_vsr(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_vsr(vbs, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_vsr(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_vsr(vp, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_vsr(vp, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_vsr(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_vsr(vi, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_vsr(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_vsr(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_vsr(vui, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_vsr(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_vsr(vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_vsr(vbi, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_vsr(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
 
   /* vec_sro */
-  res_vsc = vec_sro(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vsc = vec_sro(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vuc = vec_sro(vuc, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vuc = vec_sro(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vs  = vec_sro(vs, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vs  = vec_sro(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vus = vec_sro(vus, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vus = vec_sro(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vp  = vec_sro(vp, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vp  = vec_sro(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vi  = vec_sro(vi, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vi  = vec_sro(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vui = vec_sro(vui, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vui = vec_sro(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vf  = vec_sro(vf, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vf  = vec_sro(vf, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vsc = vec_vsro(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vsc = vec_vsro(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vuc = vec_vsro(vuc, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vuc = vec_vsro(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vs  = vec_vsro(vs, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vs  = vec_vsro(vs, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vus = vec_vsro(vus, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vus = vec_vsro(vus, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vp  = vec_vsro(vp, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vp  = vec_vsro(vp, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vi  = vec_vsro(vi, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vi  = vec_vsro(vi, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vui = vec_vsro(vui, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vui = vec_vsro(vui, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vf  = vec_vsro(vf, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vf  = vec_vsro(vf, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vsc = vec_sro(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vsc = vec_sro(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vuc = vec_sro(vuc, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vuc = vec_sro(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vs  = vec_sro(vs, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vs  = vec_sro(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vus = vec_sro(vus, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vus = vec_sro(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vp  = vec_sro(vp, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vp  = vec_sro(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vi  = vec_sro(vi, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vi  = vec_sro(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vui = vec_sro(vui, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vui = vec_sro(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vf  = vec_sro(vf, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vf  = vec_sro(vf, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vsc = vec_vsro(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vsc = vec_vsro(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vuc = vec_vsro(vuc, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vuc = vec_vsro(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vs  = vec_vsro(vs, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vs  = vec_vsro(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vus = vec_vsro(vus, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vus = vec_vsro(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vp  = vec_vsro(vp, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vp  = vec_vsro(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vi  = vec_vsro(vi, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vi  = vec_vsro(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vui = vec_vsro(vui, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vui = vec_vsro(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vf  = vec_vsro(vf, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vf  = vec_vsro(vf, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
 
   /* vec_st */
-  vec_st(vsc, 0, &vsc);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vsc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vuc, 0, &vuc);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vuc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbc, 0, &vbc);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vs, 0, &vs);                          // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vs, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vus, 0, &vus);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vus, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbs, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbs, 0, &vbs);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vp, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vp, 0, &param_us);                    // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vp, 0, &vp);                          // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vi, 0, &vi);                          // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vi, 0, &param_i);                     // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vui, 0, &vui);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vui, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbi, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbi, 0, &vbi);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vf, 0, &vf);                          // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vf, 0, &param_f);                     // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbc, 0, &vbc);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbs, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbs, 0, &vbs);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vp, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vp, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vp, 0, &vp);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbi, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbi, 0, &vbi);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vf, 0, &param_f);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
   /* vec_ste */
-  vec_ste(vsc, 0, &param_sc);                  // CHECK: @llvm.ppc.altivec.stvebx
-  vec_ste(vuc, 0, &param_uc);                  // CHECK: @llvm.ppc.altivec.stvebx
-  vec_ste(vbc, 0, &param_sc);                  // CHECK: @llvm.ppc.altivec.stvebx
-  vec_ste(vbc, 0, &param_uc);                  // CHECK: @llvm.ppc.altivec.stvebx
-  vec_ste(vs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vus, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vbs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vbs, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vp, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vp, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvewx
-  vec_ste(vui, 0, &param_ui);                  // CHECK: @llvm.ppc.altivec.stvewx
-  vec_ste(vbi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvewx
-  vec_ste(vbi, 0, &param_ui);                  // CHECK: @llvm.ppc.altivec.stvewx
-  vec_ste(vf, 0, &param_f);                    // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvebx(vsc, 0, &param_sc);               // CHECK: @llvm.ppc.altivec.stvebx
-  vec_stvebx(vuc, 0, &param_uc);               // CHECK: @llvm.ppc.altivec.stvebx
-  vec_stvebx(vbc, 0, &param_sc);               // CHECK: @llvm.ppc.altivec.stvebx
-  vec_stvebx(vbc, 0, &param_uc);               // CHECK: @llvm.ppc.altivec.stvebx
-  vec_stvehx(vs, 0, &param_s);                 // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vus, 0, &param_us);               // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vbs, 0, &param_s);                // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vbs, 0, &param_us);               // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vp, 0, &param_s);                 // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vp, 0, &param_us);                // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvewx(vi, 0, &param_i);                 // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvewx(vui, 0, &param_ui);               // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvewx(vbi, 0, &param_i);                // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvewx(vbi, 0, &param_ui);               // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvewx(vf, 0, &param_f);                 // CHECK: @llvm.ppc.altivec.stvewx
+  vec_ste(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_ste(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_ste(vbc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_ste(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_ste(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_ste(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_ste(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_ste(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_ste(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvebx(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_stvebx(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_stvebx(vbc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_stvebx(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_stvehx(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvewx(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvewx(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvewx(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvewx(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvewx(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
 
   /* vec_stl */
-  vec_stl(vsc, 0, &vsc);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vsc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vuc, 0, &vuc);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vuc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbc, 0, &vbc);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vs, 0, &vs);                          // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vs, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vus, 0, &vus);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vus, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbs, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbs, 0, &vbs);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vp, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vp, 0, &param_us);                    // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vp, 0, &vp);                          // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vi, 0, &vi);                          // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vi, 0, &param_i);                     // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vui, 0, &vui);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vui, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbi, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbi, 0, &vbi);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vf, 0, &vf);                          // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vf, 0, &param_f);                     // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbc, 0, &vbc);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbs, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbs, 0, &vbs);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vp, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vp, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vp, 0, &vp);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbi, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbi, 0, &vbi);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vf, 0, &param_f);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
   /* vec_sub */
-  res_vsc = vec_sub(vsc, vsc);                  // CHECK: sub <16 x i8>
-  res_vsc = vec_sub(vbc, vsc);                  // CHECK: sub <16 x i8>
-  res_vsc = vec_sub(vsc, vbc);                  // CHECK: sub <16 x i8>
-  res_vuc = vec_sub(vuc, vuc);                  // CHECK: sub <16 x i8>
-  res_vuc = vec_sub(vbc, vuc);                  // CHECK: sub <16 x i8>
-  res_vuc = vec_sub(vuc, vbc);                  // CHECK: sub <16 x i8>
-  res_vs  = vec_sub(vs, vs);                    // CHECK: sub <8 x i16>
-  res_vs  = vec_sub(vbs, vs);                   // CHECK: sub <8 x i16>
-  res_vs  = vec_sub(vs, vbs);                   // CHECK: sub <8 x i16>
-  res_vus = vec_sub(vus, vus);                  // CHECK: sub <8 x i16>
-  res_vus = vec_sub(vbs, vus);                  // CHECK: sub <8 x i16>
-  res_vus = vec_sub(vus, vbs);                  // CHECK: sub <8 x i16>
-  res_vi  = vec_sub(vi, vi);                    // CHECK: sub <4 x i32>
-  res_vi  = vec_sub(vbi, vi);                   // CHECK: sub <4 x i32>
-  res_vi  = vec_sub(vi, vbi);                   // CHECK: sub <4 x i32>
-  res_vui = vec_sub(vui, vui);                  // CHECK: sub <4 x i32>
-  res_vui = vec_sub(vbi, vui);                  // CHECK: sub <4 x i32>
-  res_vui = vec_sub(vui, vbi);                  // CHECK: sub <4 x i32>
-  res_vf  = vec_sub(vf, vf);                    // CHECK: fsub <4 x float>
-  res_vsc = vec_vsububm(vsc, vsc);              // CHECK: sub <16 x i8>
-  res_vsc = vec_vsububm(vbc, vsc);              // CHECK: sub <16 x i8>
-  res_vsc = vec_vsububm(vsc, vbc);              // CHECK: sub <16 x i8>
-  res_vuc = vec_vsububm(vuc, vuc);              // CHECK: sub <16 x i8>
-  res_vuc = vec_vsububm(vbc, vuc);              // CHECK: sub <16 x i8>
-  res_vuc = vec_vsububm(vuc, vbc);              // CHECK: sub <16 x i8>
-  res_vs  = vec_vsubuhm(vs, vs);                // CHECK: sub <8 x i16>
-  res_vs  = vec_vsubuhm(vbs, vus);              // CHECK: sub <8 x i16>
-  res_vs  = vec_vsubuhm(vus, vbs);              // CHECK: sub <8 x i16>
-  res_vus = vec_vsubuhm(vus, vus);              // CHECK: sub <8 x i16>
-  res_vus = vec_vsubuhm(vbs, vus);              // CHECK: sub <8 x i16>
-  res_vus = vec_vsubuhm(vus, vbs);              // CHECK: sub <8 x i16>
-  res_vi  = vec_vsubuwm(vi, vi);                // CHECK: sub <4 x i32>
-  res_vi  = vec_vsubuwm(vbi, vi);               // CHECK: sub <4 x i32>
-  res_vi  = vec_vsubuwm(vi, vbi);               // CHECK: sub <4 x i32>
-  res_vui = vec_vsubuwm(vui, vui);              // CHECK: sub <4 x i32>
-  res_vui = vec_vsubuwm(vbi, vui);              // CHECK: sub <4 x i32>
-  res_vui = vec_vsubuwm(vui, vbi);              // CHECK: sub <4 x i32>
-  res_vf  = vec_vsubfp(vf, vf);                 // CHECK: fsub <4 x float>
+  res_vsc = vec_sub(vsc, vsc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vsc = vec_sub(vbc, vsc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vsc = vec_sub(vsc, vbc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_sub(vuc, vuc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_sub(vbc, vuc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_sub(vuc, vbc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vs  = vec_sub(vs, vs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vs  = vec_sub(vbs, vs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vs  = vec_sub(vs, vbs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_sub(vus, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_sub(vbs, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_sub(vus, vbs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vi  = vec_sub(vi, vi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vi  = vec_sub(vbi, vi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vi  = vec_sub(vi, vbi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_sub(vui, vui);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_sub(vbi, vui);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_sub(vui, vbi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vf  = vec_sub(vf, vf);
+// CHECK: fsub <4 x float>
+// CHECK-LE: fsub <4 x float>
+
+  res_vsc = vec_vsububm(vsc, vsc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vsc = vec_vsububm(vbc, vsc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vsc = vec_vsububm(vsc, vbc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_vsububm(vuc, vuc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_vsububm(vbc, vuc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_vsububm(vuc, vbc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vs  = vec_vsubuhm(vs, vs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vs  = vec_vsubuhm(vbs, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vs  = vec_vsubuhm(vus, vbs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_vsubuhm(vus, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_vsubuhm(vbs, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_vsubuhm(vus, vbs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vi  = vec_vsubuwm(vi, vi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vi  = vec_vsubuwm(vbi, vi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vi  = vec_vsubuwm(vi, vbi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_vsubuwm(vui, vui);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_vsubuwm(vbi, vui);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_vsubuwm(vui, vbi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vf  = vec_vsubfp(vf, vf);
+// CHECK: fsub <4 x float>
+// CHECK-LE: fsub <4 x float>
 
   /* vec_subc */
-  res_vui = vec_subc(vui, vui);                 // CHECK: @llvm.ppc.altivec.vsubcuw
-  res_vui = vec_vsubcuw(vui, vui);              // CHECK: @llvm.ppc.altivec.vsubcuw
+  res_vui = vec_subc(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsubcuw
+// CHECK-LE: @llvm.ppc.altivec.vsubcuw
+
+  res_vui = vec_vsubcuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsubcuw
+// CHECK-LE: @llvm.ppc.altivec.vsubcuw
 
   /* vec_subs */
-  res_vsc = vec_subs(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vsc = vec_subs(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vsc = vec_subs(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vuc = vec_subs(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vsububs
-  res_vuc = vec_subs(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vsububs
-  res_vuc = vec_subs(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vsububs
-  res_vs  = vec_subs(vs, vs);                   // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vs  = vec_subs(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vs  = vec_subs(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vus = vec_subs(vus, vus);                 // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vus = vec_subs(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vus = vec_subs(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vi  = vec_subs(vi, vi);                   // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vi  = vec_subs(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vi  = vec_subs(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vui = vec_subs(vui, vui);                 // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vui = vec_subs(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vui = vec_subs(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vsc = vec_vsubsbs(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vsc = vec_vsubsbs(vbc, vsc);              // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vsc = vec_vsubsbs(vsc, vbc);              // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vuc = vec_vsububs(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vsububs
-  res_vuc = vec_vsububs(vbc, vuc);              // CHECK: @llvm.ppc.altivec.vsububs
-  res_vuc = vec_vsububs(vuc, vbc);              // CHECK: @llvm.ppc.altivec.vsububs
-  res_vs  = vec_vsubshs(vs, vs);                // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vs  = vec_vsubshs(vbs, vs);               // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vs  = vec_vsubshs(vs, vbs);               // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vus = vec_vsubuhs(vus, vus);              // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vus = vec_vsubuhs(vbs, vus);              // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vus = vec_vsubuhs(vus, vbs);              // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vi  = vec_vsubsws(vi, vi);                // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vi  = vec_vsubsws(vbi, vi);               // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vi  = vec_vsubsws(vi, vbi);               // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vui = vec_vsubuws(vui, vui);              // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vui = vec_vsubuws(vbi, vui);              // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vui = vec_vsubuws(vui, vbi);              // CHECK: @llvm.ppc.altivec.vsubuws
+  res_vsc = vec_subs(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vsc = vec_subs(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vsc = vec_subs(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vuc = vec_subs(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vuc = vec_subs(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vuc = vec_subs(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vs  = vec_subs(vs, vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vs  = vec_subs(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vs  = vec_subs(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vus = vec_subs(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vus = vec_subs(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vus = vec_subs(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vi  = vec_subs(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vi  = vec_subs(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vi  = vec_subs(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vui = vec_subs(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vui = vec_subs(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vui = vec_subs(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vsc = vec_vsubsbs(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vsc = vec_vsubsbs(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vsc = vec_vsubsbs(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vuc = vec_vsububs(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vuc = vec_vsububs(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vuc = vec_vsububs(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vs  = vec_vsubshs(vs, vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vs  = vec_vsubshs(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vs  = vec_vsubshs(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vus = vec_vsubuhs(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vus = vec_vsubuhs(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vus = vec_vsubuhs(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vi  = vec_vsubsws(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vi  = vec_vsubsws(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vi  = vec_vsubsws(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vui = vec_vsubuws(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vui = vec_vsubuws(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vui = vec_vsubuws(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
 
   /* vec_sum4s */
-  res_vi  = vec_sum4s(vsc, vi);                 // CHECK: @llvm.ppc.altivec.vsum4sbs
-  res_vui = vec_sum4s(vuc, vui);                // CHECK: @llvm.ppc.altivec.vsum4ubs
-  res_vi  = vec_sum4s(vs, vi);                  // CHECK: @llvm.ppc.altivec.vsum4shs
-  res_vi  = vec_vsum4sbs(vsc, vi);              // CHECK: @llvm.ppc.altivec.vsum4sbs
-  res_vui = vec_vsum4ubs(vuc, vui);             // CHECK: @llvm.ppc.altivec.vsum4ubs
-  res_vi  = vec_vsum4shs(vs, vi);               // CHECK: @llvm.ppc.altivec.vsum4shs
+  res_vi  = vec_sum4s(vsc, vi);
+// CHECK: @llvm.ppc.altivec.vsum4sbs
+// CHECK-LE: @llvm.ppc.altivec.vsum4sbs
+
+  res_vui = vec_sum4s(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsum4ubs
+// CHECK-LE: @llvm.ppc.altivec.vsum4ubs
+
+  res_vi  = vec_sum4s(vs, vi);
+// CHECK: @llvm.ppc.altivec.vsum4shs
+// CHECK-LE: @llvm.ppc.altivec.vsum4shs
+
+  res_vi  = vec_vsum4sbs(vsc, vi);
+// CHECK: @llvm.ppc.altivec.vsum4sbs
+// CHECK-LE: @llvm.ppc.altivec.vsum4sbs
+
+  res_vui = vec_vsum4ubs(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsum4ubs
+// CHECK-LE: @llvm.ppc.altivec.vsum4ubs
+
+  res_vi  = vec_vsum4shs(vs, vi);
+// CHECK: @llvm.ppc.altivec.vsum4shs
+// CHECK-LE: @llvm.ppc.altivec.vsum4shs
 
   /* vec_sum2s */
-  res_vi = vec_sum2s(vi, vi);                   // CHECK: @llvm.ppc.altivec.vsum2sws
-  res_vi = vec_vsum2sws(vi, vi);                // CHECK: @llvm.ppc.altivec.vsum2sws
+  res_vi = vec_sum2s(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsum2sws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vsum2sws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi = vec_vsum2sws(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsum2sws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vsum2sws
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_sums */
-  res_vi = vec_sums(vi, vi);                    // CHECK: @llvm.ppc.altivec.vsumsws
-  res_vi = vec_vsumsws(vi, vi);                 // CHECK: @llvm.ppc.altivec.vsumsws
+  res_vi = vec_sums(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsumsws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vsumsws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi = vec_vsumsws(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsumsws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vsumsws
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_trunc */
-  res_vf = vec_trunc(vf);                       // CHECK: @llvm.ppc.altivec.vrfiz
-  res_vf = vec_vrfiz(vf);                       // CHECK: @llvm.ppc.altivec.vrfiz
+  res_vf = vec_trunc(vf);
+// CHECK: @llvm.ppc.altivec.vrfiz
+// CHECK-LE: @llvm.ppc.altivec.vrfiz
+
+  res_vf = vec_vrfiz(vf);
+// CHECK: @llvm.ppc.altivec.vrfiz
+// CHECK-LE: @llvm.ppc.altivec.vrfiz
 
   /* vec_unpackh */
-  res_vs  = vec_unpackh(vsc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
-  res_vbs = vec_unpackh(vbc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
-  res_vi  = vec_unpackh(vs);                    // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vbi = vec_unpackh(vbs);                   // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vui = vec_unpackh(vp);                    // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vs  = vec_vupkhsb(vsc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
-  res_vbs = vec_vupkhsb(vbc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
-  res_vi  = vec_vupkhsh(vs);                    // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vbi = vec_vupkhsh(vbs);                   // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vui = vec_vupkhsh(vp);                    // CHECK: @llvm.ppc.altivec.vupkhsh
+  res_vs  = vec_unpackh(vsc);
+// CHECK: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
+
+  res_vbs = vec_unpackh(vbc);
+// CHECK: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
+
+  res_vi  = vec_unpackh(vs);
+// CHECK: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
+
+  res_vbi = vec_unpackh(vbs);
+// CHECK: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
+
+  res_vui = vec_unpackh(vp);
+// CHECK: @llvm.ppc.altivec.vupkhpx
+// CHECK-LE: @llvm.ppc.altivec.vupklpx
+
+  res_vs  = vec_vupkhsb(vsc);
+// CHECK: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
+
+  res_vbs = vec_vupkhsb(vbc);
+// CHECK: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
+
+  res_vi  = vec_vupkhsh(vs);
+// CHECK: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
+
+  res_vbi = vec_vupkhsh(vbs);
+// CHECK: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
+
+  res_vui = vec_vupkhsh(vp);
+// CHECK: @llvm.ppc.altivec.vupkhpx
+// CHECK-LE: @llvm.ppc.altivec.vupklpx
 
   /* vec_unpackl */
-  res_vs  = vec_unpackl(vsc);                   // CHECK: @llvm.ppc.altivec.vupklsb
-  res_vbs = vec_unpackl(vbc);                   // CHECK: @llvm.ppc.altivec.vupklsb
-  res_vi  = vec_unpackl(vs);                    // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vbi = vec_unpackl(vbs);                   // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vui = vec_unpackl(vp);                    // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vs  = vec_vupklsb(vsc);                   // CHECK: @llvm.ppc.altivec.vupklsb
-  res_vbs = vec_vupklsb(vbc);                   // CHECK: @llvm.ppc.altivec.vupklsb
-  res_vi  = vec_vupklsh(vs);                    // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vbi = vec_vupklsh(vbs);                   // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vui = vec_vupklsh(vp);                    // CHECK: @llvm.ppc.altivec.vupklsh
+  res_vs  = vec_unpackl(vsc);
+// CHECK: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+
+  res_vbs = vec_unpackl(vbc);
+// CHECK: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+
+  res_vi  = vec_unpackl(vs);
+// CHECK: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+
+  res_vbi = vec_unpackl(vbs);
+// CHECK: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+
+  res_vui = vec_unpackl(vp);
+// CHECK: @llvm.ppc.altivec.vupklpx
+// CHECK-LE: @llvm.ppc.altivec.vupkhpx
+
+  res_vs  = vec_vupklsb(vsc);
+// CHECK: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+
+  res_vbs = vec_vupklsb(vbc);
+// CHECK: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+
+  res_vi  = vec_vupklsh(vs);
+// CHECK: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+
+  res_vbi = vec_vupklsh(vbs);
+// CHECK: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+
+  res_vui = vec_vupklsh(vp);
+// CHECK: @llvm.ppc.altivec.vupklpx
+// CHECK-LE: @llvm.ppc.altivec.vupkhpx
 
   /* vec_xor */
-  res_vsc = vec_xor(vsc, vsc);                  // CHECK: xor <16 x i8>
-  res_vsc = vec_xor(vbc, vsc);                  // CHECK: xor <16 x i8>
-  res_vsc = vec_xor(vsc, vbc);                  // CHECK: xor <16 x i8>
-  res_vuc = vec_xor(vuc, vuc);                  // CHECK: xor <16 x i8>
-  res_vuc = vec_xor(vbc, vuc);                  // CHECK: xor <16 x i8>
-  res_vuc = vec_xor(vuc, vbc);                  // CHECK: xor <16 x i8>
-  res_vbc = vec_xor(vbc, vbc);                  // CHECK: xor <16 x i8>
-  res_vs  = vec_xor(vs, vs);                    // CHECK: xor <8 x i16>
-  res_vs  = vec_xor(vbs, vs);                   // CHECK: xor <8 x i16>
-  res_vs  = vec_xor(vs, vbs);                   // CHECK: xor <8 x i16>
-  res_vus = vec_xor(vus, vus);                  // CHECK: xor <8 x i16>
-  res_vus = vec_xor(vbs, vus);                  // CHECK: xor <8 x i16>
-  res_vus = vec_xor(vus, vbs);                  // CHECK: xor <8 x i16>
-  res_vbs = vec_xor(vbs, vbs);                  // CHECK: xor <8 x i16>
-  res_vi  = vec_xor(vi, vi);                    // CHECK: xor <4 x i32>
-  res_vi  = vec_xor(vbi, vi);                   // CHECK: xor <4 x i32>
-  res_vi  = vec_xor(vi, vbi);                   // CHECK: xor <4 x i32>
-  res_vui = vec_xor(vui, vui);                  // CHECK: xor <4 x i32>
-  res_vui = vec_xor(vbi, vui);                  // CHECK: xor <4 x i32>
-  res_vui = vec_xor(vui, vbi);                  // CHECK: xor <4 x i32>
-  res_vbi = vec_xor(vbi, vbi);                  // CHECK: xor <4 x i32>
-  res_vf  = vec_xor(vf, vf);                    // CHECK: xor <4 x i32>
-  res_vf  = vec_xor(vbi, vf);                   // CHECK: xor <4 x i32>
-  res_vf  = vec_xor(vf, vbi);                   // CHECK: xor <4 x i32>
-  res_vsc = vec_vxor(vsc, vsc);                 // CHECK: xor <16 x i8>
-  res_vsc = vec_vxor(vbc, vsc);                 // CHECK: xor <16 x i8>
-  res_vsc = vec_vxor(vsc, vbc);                 // CHECK: xor <16 x i8>
-  res_vuc = vec_vxor(vuc, vuc);                 // CHECK: xor <16 x i8>
-  res_vuc = vec_vxor(vbc, vuc);                 // CHECK: xor <16 x i8>
-  res_vuc = vec_vxor(vuc, vbc);                 // CHECK: xor <16 x i8>
-  res_vbc = vec_vxor(vbc, vbc);                 // CHECK: xor <16 x i8>
-  res_vs  = vec_vxor(vs, vs);                   // CHECK: xor <8 x i16>
-  res_vs  = vec_vxor(vbs, vs);                  // CHECK: xor <8 x i16>
-  res_vs  = vec_vxor(vs, vbs);                  // CHECK: xor <8 x i16>
-  res_vus = vec_vxor(vus, vus);                 // CHECK: xor <8 x i16>
-  res_vus = vec_vxor(vbs, vus);                 // CHECK: xor <8 x i16>
-  res_vus = vec_vxor(vus, vbs);                 // CHECK: xor <8 x i16>
-  res_vbs = vec_vxor(vbs, vbs);                 // CHECK: xor <8 x i16>
-  res_vi  = vec_vxor(vi, vi);                   // CHECK: xor <4 x i32>
-  res_vi  = vec_vxor(vbi, vi);                  // CHECK: xor <4 x i32>
-  res_vi  = vec_vxor(vi, vbi);                  // CHECK: xor <4 x i32>
-  res_vui = vec_vxor(vui, vui);                 // CHECK: xor <4 x i32>
-  res_vui = vec_vxor(vbi, vui);                 // CHECK: xor <4 x i32>
-  res_vui = vec_vxor(vui, vbi);                 // CHECK: xor <4 x i32>
-  res_vbi = vec_vxor(vbi, vbi);                 // CHECK: xor <4 x i32>
-  res_vf  = vec_vxor(vf, vf);                   // CHECK: xor <4 x i32>
-  res_vf  = vec_vxor(vbi, vf);                  // CHECK: xor <4 x i32>
-  res_vf  = vec_vxor(vf, vbi);                  // CHECK: xor <4 x i32>
+  res_vsc = vec_xor(vsc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vsc = vec_xor(vbc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vsc = vec_xor(vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_xor(vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_xor(vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_xor(vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vbc = vec_xor(vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vs  = vec_xor(vs, vs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vs  = vec_xor(vbs, vs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vs  = vec_xor(vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_xor(vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_xor(vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_xor(vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vbs = vec_xor(vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vi  = vec_xor(vi, vi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vi  = vec_xor(vbi, vi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vi  = vec_xor(vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_xor(vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_xor(vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_xor(vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vbi = vec_xor(vbi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_xor(vf, vf);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_xor(vbi, vf);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_xor(vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vsc = vec_vxor(vsc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vsc = vec_vxor(vbc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vsc = vec_vxor(vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_vxor(vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_vxor(vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_vxor(vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vbc = vec_vxor(vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vs  = vec_vxor(vs, vs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vs  = vec_vxor(vbs, vs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vs  = vec_vxor(vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_vxor(vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_vxor(vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_vxor(vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vbs = vec_vxor(vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vi  = vec_vxor(vi, vi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vi  = vec_vxor(vbi, vi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vi  = vec_vxor(vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_vxor(vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_vxor(vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_vxor(vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vbi = vec_vxor(vbi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_vxor(vf, vf);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_vxor(vbi, vf);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_vxor(vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
   /* ------------------------------ extensions -------------------------------------- */
 
   /* vec_extract */
-  res_sc = vec_extract(vsc, param_i);           // CHECK: extractelement <16 x i8>
-  res_uc = vec_extract(vuc, param_i);           // CHECK: extractelement <16 x i8>
-  res_s  = vec_extract(vs, param_i);            // CHECK: extractelement <8 x i16>
-  res_us = vec_extract(vus, param_i);           // CHECK: extractelement <8 x i16>
-  res_i  = vec_extract(vi, param_i);            // CHECK: extractelement <4 x i32>
-  res_ui = vec_extract(vui, param_i);           // CHECK: extractelement <4 x i32>
-  res_f  = vec_extract(vf, param_i);            // CHECK: extractelement <4 x float>
+  res_sc = vec_extract(vsc, param_i);
+// CHECK: extractelement <16 x i8>
+// CHECK-LE: extractelement <16 x i8>
+
+  res_uc = vec_extract(vuc, param_i);
+// CHECK: extractelement <16 x i8>
+// CHECK-LE: extractelement <16 x i8>
+
+  res_s  = vec_extract(vs, param_i);
+// CHECK: extractelement <8 x i16>
+// CHECK-LE: extractelement <8 x i16>
+
+  res_us = vec_extract(vus, param_i);
+// CHECK: extractelement <8 x i16>
+// CHECK-LE: extractelement <8 x i16>
+
+  res_i  = vec_extract(vi, param_i);
+// CHECK: extractelement <4 x i32>
+// CHECK-LE: extractelement <4 x i32>
+
+  res_ui = vec_extract(vui, param_i);
+// CHECK: extractelement <4 x i32>
+// CHECK-LE: extractelement <4 x i32>
+
+  res_f  = vec_extract(vf, param_i);
+// CHECK: extractelement <4 x float>
+// CHECK-LE: extractelement <4 x float>
 
   /* vec_insert */
-  res_vsc = vec_insert(param_sc, vsc, param_i); // CHECK: insertelement <16 x i8>
-  res_vuc = vec_insert(param_uc, vuc, param_i); // CHECK: insertelement <16 x i8>
-  res_vs  = vec_insert(param_s, vs, param_i);   // CHECK: insertelement <8 x i16>
-  res_vus = vec_insert(param_us, vus, param_i); // CHECK: insertelement <8 x i16>
-  res_vi  = vec_insert(param_i, vi, param_i);   // CHECK: insertelement <4 x i32>
-  res_vui = vec_insert(param_ui, vui, param_i); // CHECK: insertelement <4 x i32>
-  res_vf  = vec_insert(param_f, vf, param_i);   // CHECK: insertelement <4 x float>
+  res_vsc = vec_insert(param_sc, vsc, param_i);
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: insertelement <16 x i8>
+
+  res_vuc = vec_insert(param_uc, vuc, param_i);
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: insertelement <16 x i8>
+
+  res_vs  = vec_insert(param_s, vs, param_i);
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: insertelement <8 x i16>
+
+  res_vus = vec_insert(param_us, vus, param_i);
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: insertelement <8 x i16>
+
+  res_vi  = vec_insert(param_i, vi, param_i);
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: insertelement <4 x i32>
+
+  res_vui = vec_insert(param_ui, vui, param_i);
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: insertelement <4 x i32>
+
+  res_vf  = vec_insert(param_f, vf, param_i);
+// CHECK: insertelement <4 x float>
+// CHECK-LE: insertelement <4 x float>
 
   /* vec_lvlx */
-  res_vsc = vec_lvlx(0, &param_sc);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvlx(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vsc = vec_lvlx(0, &vsc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvlx(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvlx(0, &param_uc);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvlx(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvlx(0, &vuc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvlx(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbc = vec_lvlx(0, &vbc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_lvlx(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvlx(0, &param_s);              // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvlx(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvlx(0, &vs);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvlx(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvlx(0, &param_us);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvlx(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvlx(0, &vus);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvlx(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbs = vec_lvlx(0, &vbs);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_lvlx(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vp  = vec_lvlx(0, &vp);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_lvlx(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvlx(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvlx(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvlx(0, &vi);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvlx(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvlx(0, &param_ui);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvlx(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvlx(0, &vui);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvlx(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbi = vec_lvlx(0, &vbi);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_lvlx(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vf  = vec_lvlx(0, &vf);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_lvlx(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_lvlxl */
-  res_vsc = vec_lvlxl(0, &param_sc);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvlxl(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vsc = vec_lvlxl(0, &vsc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvlxl(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvlxl(0, &param_uc);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvlxl(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvlxl(0, &vuc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvlxl(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbc = vec_lvlxl(0, &vbc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_lvlxl(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvlxl(0, &param_s);             // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvlxl(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvlxl(0, &vs);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvlxl(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvlxl(0, &param_us);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvlxl(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvlxl(0, &vus);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvlxl(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbs = vec_lvlxl(0, &vbs);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_lvlxl(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vp  = vec_lvlxl(0, &vp);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_lvlxl(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvlxl(0, &param_i);             // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvlxl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvlxl(0, &vi);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvlxl(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvlxl(0, &param_ui);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvlxl(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvlxl(0, &vui);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvlxl(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbi = vec_lvlxl(0, &vbi);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_lvlxl(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vf  = vec_lvlxl(0, &vf);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_lvlxl(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_lvrx */
-  res_vsc = vec_lvrx(0, &param_sc);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvrx(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vsc = vec_lvrx(0, &vsc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvrx(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvrx(0, &param_uc);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvrx(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvrx(0, &vuc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvrx(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbc = vec_lvrx(0, &vbc);                  // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_lvrx(0, &vbc);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvrx(0, &param_s);              // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvrx(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvrx(0, &vs);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvrx(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvrx(0, &param_us);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvrx(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvrx(0, &vus);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvrx(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbs = vec_lvrx(0, &vbs);                  // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_lvrx(0, &vbs);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vp  = vec_lvrx(0, &vp);                   // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_lvrx(0, &vp);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvrx(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvrx(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvrx(0, &vi);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvrx(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvrx(0, &param_ui);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvrx(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvrx(0, &vui);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvrx(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbi = vec_lvrx(0, &vbi);                  // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_lvrx(0, &vbi);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vf  = vec_lvrx(0, &vf);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_lvrx(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_lvrxl */
-  res_vsc = vec_lvrxl(0, &param_sc);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvrxl(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vsc = vec_lvrxl(0, &vsc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvrxl(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvrxl(0, &param_uc);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvrxl(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvrxl(0, &vuc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvrxl(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbc = vec_lvrxl(0, &vbc);                 // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_lvrxl(0, &vbc);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvrxl(0, &param_s);             // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvrxl(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvrxl(0, &vs);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvrxl(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvrxl(0, &param_us);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvrxl(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvrxl(0, &vus);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvrxl(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbs = vec_lvrxl(0, &vbs);                 // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_lvrxl(0, &vbs);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vp  = vec_lvrxl(0, &vp);                  // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_lvrxl(0, &vp);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvrxl(0, &param_i);             // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvrxl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvrxl(0, &vi);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvrxl(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvrxl(0, &param_ui);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvrxl(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvrxl(0, &vui);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvrxl(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbi = vec_lvrxl(0, &vbi);                 // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_lvrxl(0, &vbi);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vf  = vec_lvrxl(0, &vf);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_lvrxl(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_stvlx */
-  vec_stvlx(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vbc, 0, &vbc);                      // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vbc, 0, &vbc);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vbs, 0, &vbs);                      // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vbs, 0, &vbs);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vp, 0, &vp);                        // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vp, 0, &vp);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vbi, 0, &vbi);                      // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vbi, 0, &vbi);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
   /* vec_stvlxl */
-  vec_stvlxl(vsc, 0, &param_sc);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vsc, 0, &vsc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vuc, 0, &param_uc);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vuc, 0, &vuc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vbc, 0, &vbc);                     // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vbc, 0, &vbc);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vs, 0, &vs);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vus, 0, &param_us);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vus, 0, &vus);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vbs, 0, &vbs);                     // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vbs, 0, &vbs);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vp, 0, &vp);                       // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vp, 0, &vp);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vi, 0, &vi);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vui, 0, &param_ui);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vui, 0, &vui);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vbi, 0, &vbi);                     // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vbi, 0, &vbi);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vf, 0, &vf);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
   /* vec_stvrx */
-  vec_stvrx(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vbc, 0, &vbc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vbs, 0, &vbs);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vp, 0, &vp);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vbi, 0, &vbi);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
   /* vec_stvrxl */
-  vec_stvrxl(vsc, 0, &param_sc);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vsc, 0, &vsc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vuc, 0, &param_uc);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vuc, 0, &vuc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vbc, 0, &vbc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vs, 0, &vs);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vus, 0, &param_us);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vus, 0, &vus);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vbs, 0, &vbs);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vp, 0, &vp);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vi, 0, &vi);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vui, 0, &param_ui);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vui, 0, &vui);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vbi, 0, &vbi);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vf, 0, &vf);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
   /* vec_promote */
-  res_vsc = vec_promote(param_sc, 0);           // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: insertelement <16 x i8>
+  res_vsc = vec_promote(param_sc, 0);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: insertelement <16 x i8>
 
-  res_vuc = vec_promote(param_uc, 0);           // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: insertelement <16 x i8>
+  res_vuc = vec_promote(param_uc, 0);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: insertelement <16 x i8>
 
-  res_vs  = vec_promote(param_s, 0);            // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: insertelement <8 x i16>
+  res_vs  = vec_promote(param_s, 0);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: insertelement <8 x i16>
 
-  res_vus = vec_promote(param_us, 0);           // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: insertelement <8 x i16>
+  res_vus = vec_promote(param_us, 0);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: insertelement <8 x i16>
 
-  res_vi  = vec_promote(param_i, 0);            // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: insertelement <4 x i32>
+  res_vi  = vec_promote(param_i, 0);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: insertelement <4 x i32>
 
-  res_vui = vec_promote(param_ui, 0);           // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: insertelement <4 x i32>
+  res_vui = vec_promote(param_ui, 0);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: insertelement <4 x i32>
 
-  res_vf  = vec_promote(param_f, 0);            // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: insertelement <4 x float>
+  res_vf  = vec_promote(param_f, 0);
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: insertelement <4 x float>
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: insertelement <4 x float>
 
   /* vec_splats */
-  res_vsc = vec_splats(param_sc);               // CHECK: insertelement <16 x i8>
+  res_vsc = vec_splats(param_sc);
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: insertelement <16 x i8>
 
-  res_vuc = vec_splats(param_uc);               // CHECK: insertelement <16 x i8>
+  res_vuc = vec_splats(param_uc);
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: insertelement <16 x i8>
 
-  res_vs  = vec_splats(param_s);                // CHECK: insertelement <8 x i16>
+  res_vs  = vec_splats(param_s);
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: insertelement <8 x i16>
 
-  res_vus = vec_splats(param_us);               // CHECK: insertelement <8 x i16>
+  res_vus = vec_splats(param_us);
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: insertelement <8 x i16>
 
-  res_vi  = vec_splats(param_i);                // CHECK: insertelement <4 x i32>
+  res_vi  = vec_splats(param_i);
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: insertelement <4 x i32>
 
-  res_vui = vec_splats(param_ui);               // CHECK: insertelement <4 x i32>
+  res_vui = vec_splats(param_ui);
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: insertelement <4 x i32>
 
-  res_vf  = vec_splats(param_f);                // CHECK: insertelement <4 x float>
+  res_vf  = vec_splats(param_f);
+// CHECK: insertelement <4 x float>
+// CHECK-LE: insertelement <4 x float>
 
   /* ------------------------------ predicates -------------------------------------- */
 
   /* vec_all_eq */
-  res_i = vec_all_eq(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_all_eq(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vp, vp);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_all_ge */
-  res_i = vec_all_ge(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_ge(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_ge(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_ge(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_ge(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_ge(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_ge(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_all_ge(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_ge(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_ge(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_ge(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_ge(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_ge(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_ge(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_gt */
-  res_i = vec_all_gt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_gt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_gt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_gt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_gt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_gt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_gt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_all_gt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_gt(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_gt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_gt(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_gt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_gt(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_gt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_in */
-  res_i = vec_all_in(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpbfp.p
+  res_i = vec_all_in(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpbfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpbfp.p
 
   /* vec_all_le */
-  res_i = vec_all_le(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_le(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_le(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_le(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_le(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_le(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_le(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_all_le(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_le(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_le(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_le(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_le(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_le(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_le(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_lt */
-  res_i = vec_all_lt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_lt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_lt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_lt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_lt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_lt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_lt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_all_lt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_lt(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_lt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_lt(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_lt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_lt(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_lt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_nan */
-  res_i = vec_all_nan(vf);                      // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_all_nan(vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /*  vec_all_ne */
-  res_i = vec_all_ne(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_all_ne(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vp, vp);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_all_nge */
-  res_i = vec_all_nge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_all_nge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_ngt */
-  res_i = vec_all_ngt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_all_ngt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_nle */
-  res_i = vec_all_nle(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_all_nle(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_nlt */
-  res_i = vec_all_nlt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_all_nlt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_numeric */
-  res_i = vec_all_numeric(vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_all_numeric(vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /*  vec_any_eq */
-  res_i = vec_any_eq(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_any_eq(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vp, vp);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_ge */
-  res_i = vec_any_ge(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_ge(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_ge(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_ge(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_ge(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_ge(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_ge(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_any_ge(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_ge(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_ge(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_ge(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_ge(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_ge(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_ge(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_gt */
-  res_i = vec_any_gt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_gt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_gt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_gt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_gt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_gt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_gt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_any_gt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_gt(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_gt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_gt(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_gt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_gt(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_gt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_le */
-  res_i = vec_any_le(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_le(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_le(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_le(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_le(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_le(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_le(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_any_le(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_le(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_le(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_le(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_le(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_le(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_le(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_lt */
-  res_i = vec_any_lt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_lt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_lt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_lt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_lt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_lt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_lt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_any_lt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_lt(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_lt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_lt(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_lt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_lt(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_lt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_nan */
-  res_i = vec_any_nan(vf);                      // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_any_nan(vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_ne */
-  res_i = vec_any_ne(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_any_ne(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vp, vp);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_nge */
-  res_i = vec_any_nge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_any_nge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_ngt */
-  res_i = vec_any_ngt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_any_ngt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_nle */
-  res_i = vec_any_nle(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_any_nle(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_nlt */
-  res_i = vec_any_nlt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_any_nlt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_numeric */
-  res_i = vec_any_numeric(vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_any_numeric(vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_out */
-  res_i = vec_any_out(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpbfp.p
+  res_i = vec_any_out(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpbfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpbfp.p
 }
 
 /* ------------------------------ Relational Operators ------------------------------ */
@@ -3059,58 +8551,183 @@
 void test7() {
   vector signed char vsc1 = (vector signed char)(-1);
   vector signed char vsc2 = (vector signed char)(-2);
-  res_i = (vsc1 == vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
-  res_i = (vsc1 != vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
-  res_i = (vsc1 <  vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
-  res_i = (vsc1 >  vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
-  res_i = (vsc1 <= vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
-  res_i = (vsc1 >= vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+  res_i = (vsc1 == vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p(i32 2
+
+  res_i = (vsc1 != vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p(i32 0
+
+  res_i = (vsc1 <  vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+
+  res_i = (vsc1 >  vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+
+  res_i = (vsc1 <= vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+
+  res_i = (vsc1 >= vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+
   vector unsigned char vuc1 = (vector unsigned char)(1);
   vector unsigned char vuc2 = (vector unsigned char)(2);
-  res_i = (vuc1 == vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
-  res_i = (vuc1 != vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
-  res_i = (vuc1 <  vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
-  res_i = (vuc1 >  vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
-  res_i = (vuc1 <= vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
-  res_i = (vuc1 >= vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+  res_i = (vuc1 == vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p(i32 2
+
+  res_i = (vuc1 != vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p(i32 0
+
+  res_i = (vuc1 <  vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+
+  res_i = (vuc1 >  vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+
+  res_i = (vuc1 <= vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+
+  res_i = (vuc1 >= vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+
   vector short vs1 = (vector short)(-1);
   vector short vs2 = (vector short)(-2);
-  res_i = (vs1 == vs2);                    // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
-  res_i = (vs1 != vs2);                    // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
-  res_i = (vs1 <  vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
-  res_i = (vs1 >  vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
-  res_i = (vs1 <= vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
-  res_i = (vs1 >= vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+  res_i = (vs1 == vs2);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p(i32 2
+
+  res_i = (vs1 != vs2);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p(i32 0
+
+  res_i = (vs1 <  vs2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+
+  res_i = (vs1 >  vs2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+
+  res_i = (vs1 <= vs2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+
+  res_i = (vs1 >= vs2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+
   vector unsigned short vus1 = (vector unsigned short)(1);
   vector unsigned short vus2 = (vector unsigned short)(2);
-  res_i = (vus1 == vus2);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
-  res_i = (vus1 != vus2);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
-  res_i = (vus1 <  vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
-  res_i = (vus1 >  vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
-  res_i = (vus1 <= vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
-  res_i = (vus1 >= vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+  res_i = (vus1 == vus2);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p(i32 2
+
+  res_i = (vus1 != vus2);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p(i32 0
+
+  res_i = (vus1 <  vus2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+
+  res_i = (vus1 >  vus2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+
+  res_i = (vus1 <= vus2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+
+  res_i = (vus1 >= vus2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+
   vector int vi1 = (vector int)(-1);
   vector int vi2 = (vector int)(-2);
-  res_i = (vi1 == vi2);                    // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
-  res_i = (vi1 != vi2);                    // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
-  res_i = (vi1 <  vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
-  res_i = (vi1 >  vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
-  res_i = (vi1 <= vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
-  res_i = (vi1 >= vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+  res_i = (vi1 == vi2);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p(i32 2
+
+  res_i = (vi1 != vi2);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p(i32 0
+
+  res_i = (vi1 <  vi2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+
+  res_i = (vi1 >  vi2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+
+  res_i = (vi1 <= vi2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+
+  res_i = (vi1 >= vi2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+
   vector unsigned int vui1 = (vector unsigned int)(1);
   vector unsigned int vui2 = (vector unsigned int)(2);
-  res_i = (vui1 == vui2);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
-  res_i = (vui1 != vui2);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
-  res_i = (vui1 <  vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
-  res_i = (vui1 >  vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
-  res_i = (vui1 <= vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
-  res_i = (vui1 >= vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+  res_i = (vui1 == vui2);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p(i32 2
+
+  res_i = (vui1 != vui2);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p(i32 0
+
+  res_i = (vui1 <  vui2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+
+  res_i = (vui1 >  vui2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+
+  res_i = (vui1 <= vui2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+
+  res_i = (vui1 >= vui2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+
   vector float vf1 = (vector float)(1.0);
   vector float vf2 = (vector float)(2.0);
-  res_i = (vf1 == vf2);                    // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 2
-  res_i = (vf1 != vf2);                    // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 0
-  res_i = (vf1 <  vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
-  res_i = (vf1 >  vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
-  res_i = (vf1 <= vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
-  res_i = (vf1 >= vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+  res_i = (vf1 == vf2);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p(i32 2
+
+  res_i = (vf1 != vf2);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p(i32 0
+
+  res_i = (vf1 <  vf2);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+
+  res_i = (vf1 >  vf2);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+
+  res_i = (vf1 <= vf2);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+
+  res_i = (vf1 >= vf2);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p(i32 2
 }
diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c
index 6df005d..0f038b8 100644
--- a/test/CodeGen/builtins-x86.c
+++ b/test/CodeGen/builtins-x86.c
@@ -266,6 +266,7 @@
 
   tmp_i = __builtin_ia32_rdtsc();
   tmp_i = __builtin_ia32_rdtscp(&tmp_Ui);
+  tmp_LLi = __builtin_ia32_rdpmc(tmp_i);
 #ifdef USE_64
   tmp_LLi = __builtin_ia32_cvtss2si64(tmp_V4f);
 #endif
@@ -451,9 +452,6 @@
   tmp_i = __builtin_ia32_movmskps256(tmp_V8f);
   __builtin_ia32_vzeroall();
   __builtin_ia32_vzeroupper();
-  tmp_V4f = __builtin_ia32_vbroadcastss(tmp_fCp);
-  tmp_V4d = __builtin_ia32_vbroadcastsd256(tmp_dCp);
-  tmp_V8f = __builtin_ia32_vbroadcastss256(tmp_fCp);
   tmp_V4d = __builtin_ia32_vbroadcastf128_pd256(tmp_V2dCp);
   tmp_V8f = __builtin_ia32_vbroadcastf128_ps256(tmp_V4fCp);
   __builtin_ia32_storeupd256(tmp_dp, tmp_V4d);
diff --git a/test/CodeGen/builtinshufflevector2.c b/test/CodeGen/builtinshufflevector2.c
index 04405b5..8712c99 100644
--- a/test/CodeGen/builtinshufflevector2.c
+++ b/test/CodeGen/builtinshufflevector2.c
@@ -6,23 +6,23 @@
 // CHECK-LABEL: define void @clang_shufflevector_v_v(
 void clang_shufflevector_v_v( float4* A, float4 x, uint4 mask ) {
 // CHECK: [[MASK:%.*]] = and <4 x i32> {{%.*}}, <i32 3, i32 3, i32 3, i32 3>
-// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 0
-// CHECK: [[E:%.*]] = extractelement <4 x float> [[X:%.*]], i32 [[I]]
+// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i{{[0-9]+}} 0
+// CHECK: [[E:%.*]] = extractelement <4 x float> [[X:%.*]], i{{[0-9]+}} [[I]]
 //
 // Here is where ToT Clang code generation makes a mistake.  
 // It uses [[I]] as the insertion index instead of 0.
 // Similarly on the remaining insertelement.
-// CHECK: [[V:%[a-zA-Z0-9._]+]] = insertelement <4 x float> undef, float [[E]], i32 0
+// CHECK: [[V:%[a-zA-Z0-9._]+]] = insertelement <4 x float> undef, float [[E]], i{{[0-9]+}} 0
 
-// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 1
-// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V2:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 1
-// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 2
-// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[E]], i32 2
-// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 3
-// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V4:%.*]] = insertelement <4 x float> [[V3]], float [[E]], i32 3
+// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i{{[0-9]+}} 1
+// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i{{[0-9]+}} [[I]]
+// CHECK: [[V2:%.*]] = insertelement <4 x float> [[V]], float [[E]], i{{[0-9]+}} 1
+// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i{{[0-9]+}} 2
+// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i{{[0-9]+}} [[I]]
+// CHECK: [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[E]], i{{[0-9]+}} 2
+// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i{{[0-9]+}} 3
+// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i{{[0-9]+}} [[I]]
+// CHECK: [[V4:%.*]] = insertelement <4 x float> [[V3]], float [[E]], i{{[0-9]+}} 3
 // CHECK: store <4 x float> [[V4]], <4 x float>* {{%.*}},
   *A = __builtin_shufflevector( x, mask );
 }
diff --git a/test/CodeGen/captured-statements-nested.c b/test/CodeGen/captured-statements-nested.c
index d8ec746..2ff9ee9 100644
--- a/test/CodeGen/captured-statements-nested.c
+++ b/test/CodeGen/captured-statements-nested.c
@@ -8,11 +8,12 @@
   char c;
 };
 
-void test_nest_captured_stmt(int param) {
+void test_nest_captured_stmt(int param, int size, int param_arr[size]) {
   int w;
-  // CHECK1: %struct.anon{{.*}} = type { i32*, i32* }
-  // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i32**, i32* }
-  // CHECK1: [[T:%struct.anon.*]] = type { i32*, i32*, %struct.A*, i32**, i32* }
+  int arr[param][size];
+  // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i{{.+}}*, i32**, i32* }
+  // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i32**, i32*, i{{.+}}*, i32**, i32* }
+  // CHECK1: [[T:%struct.anon.*]] = type { i32*, i32*, %struct.A*, i32**, i32*, i{{.+}}*, i32**, i32* }
   #pragma clang __debug captured
   {
     int x;
@@ -26,13 +27,15 @@
         *y = param;
         z.b = 0.1f;
         z.c = 'c';
+        param_arr[size - 1] = 2;
+        arr[10][z.a] = 12;
 
         // CHECK1: define internal void @__captured_stmt{{.*}}([[T]]
         //
         // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
         // CHECK1-NEXT: load %struct.A**
         // CHECK1-NEXT: getelementptr inbounds %struct.A*
-        // CHECK1-NEXT: store i32 1
+        // CHECK1-NEXT: store i{{.+}} 1
         //
         // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 1
         // CHECK1-NEXT: load i32**
@@ -59,6 +62,27 @@
         // CHECK1-NEXT: load %struct.A**
         // CHECK1-NEXT: getelementptr inbounds %struct.A*
         // CHECK1-NEXT: store i8 99
+        //
+        // CHECK1: [[SIZE_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 5
+        // CHECK1-DAG: [[SIZE_ADDR:%.*]] = load i{{.+}}** [[SIZE_ADDR_REF]]
+        // CHECK1-DAG: [[SIZE:%.*]] = load i{{.+}}* [[SIZE_ADDR]]
+        // CHECK1-DAG: [[PARAM_ARR_IDX:%.*]] = sub nsw i{{.+}} [[SIZE]], 1
+        // CHECK1-DAG: [[PARAM_ARR_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 6
+        // CHECK1-DAG: [[PARAM_ARR_ADDR:%.*]] = load i{{.+}}*** [[PARAM_ARR_ADDR_REF]]
+        // CHECK1-DAG: [[PARAM_ARR:%.*]] = load i{{.+}}** [[PARAM_ARR_ADDR]]
+        // CHECK1-DAG: [[PARAM_ARR_SIZE_MINUS_1_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[PARAM_ARR]], i{{.*}}
+        // CHECK1: store i{{.+}} 2, i{{.+}}* [[PARAM_ARR_SIZE_MINUS_1_ADDR]]
+        //
+        // CHECK1: [[Z_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 2
+        // CHECK1-DAG: [[Z_ADDR:%.*]] = load %struct.A** [[Z_ADDR_REF]]
+        // CHECK1-DAG: [[Z_A_ADDR:%.*]] = getelementptr inbounds %struct.A* [[Z_ADDR]], i{{.+}} 0, i{{.+}} 0
+        // CHECK1-DAG: [[ARR_IDX_2:%.*]] = load i{{.+}}* [[Z_A_ADDR]]
+        // CHECK1-DAG: [[ARR_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 7
+        // CHECK1-DAG: [[ARR_ADDR:%.*]] = load i{{.+}}** [[ARR_ADDR_REF]]
+        // CHECK1-DAG: [[ARR_IDX_1:%.*]] = mul {{.*}} 10
+        // CHECK1-DAG: [[ARR_10_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[ARR_ADDR]], i{{.*}} [[ARR_IDX_1]]
+        // CHECK1-DAG: [[ARR_10_Z_A_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[ARR_10_ADDR]], i{{.*}}
+        // CHECK1: store i{{.+}} 12, i{{.+}}* [[ARR_10_Z_A_ADDR]]
       }
     }
   }
diff --git a/test/CodeGen/captured-statements.c b/test/CodeGen/captured-statements.c
index b52d115..85d597a 100644
--- a/test/CodeGen/captured-statements.c
+++ b/test/CodeGen/captured-statements.c
@@ -48,17 +48,31 @@
 // CHECK-2:   %i = alloca i32
 
 // Capture array
-void test3() {
+void test3(int size) {
   int arr[] = {1, 2, 3, 4, 5};
+  int vla_arr[size];
   #pragma clang __debug captured
   {
-    arr[2] = arr[1];
+    arr[2] = vla_arr[size - 1];
   }
   // CHECK-3: test3
   // CHECK-3: alloca [5 x i32]
   // CHECK-3: call void @__captured_stmt
 }
 
+// Capture VLA array
+void test4(int size, int vla_arr[size]) {
+  #pragma clang __debug captured
+  {
+    vla_arr[0] = 1;
+  }
+  // CHECK-3: test4([[INT:i.+]] {{.*}}[[SIZE:%.+]], [[INT]]*
+  // CHECK-3: store [[INT]] {{.*}}[[SIZE]], [[INT]]* [[SIZE_ADDR:%.+]],
+  // CHECK-3: [[REF:%.+]] = getelementptr inbounds
+  // CHECK-3: store [[INT]]* [[SIZE_ADDR]], [[INT]]** [[REF]]
+  // CHECK-3: call void @__captured_stmt
+}
+
 void dont_capture_global() {
   static int s;
   extern int e;
diff --git a/test/CodeGen/dependent-lib.c b/test/CodeGen/dependent-lib.c
index df4aaf0..20913d3 100644
--- a/test/CodeGen/dependent-lib.c
+++ b/test/CodeGen/dependent-lib.c
@@ -2,13 +2,13 @@
 // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s
 
-// CHECK: !llvm.module.flags = !{!0}
-// CHECK: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
+// CHECK: !llvm.module.flags = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
 // CHECK: ![[link_opts]] = metadata !{metadata ![[msvcrt:[0-9]+]]}
 // CHECK: ![[msvcrt]] = metadata !{metadata !"/DEFAULTLIB:msvcrt.lib"}
 
-// LINUX: !llvm.module.flags = !{!0}
-// LINUX: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
+// LINUX: !llvm.module.flags = !{{{.*}}}
+// LINUX: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
 // LINUX: ![[link_opts]] = metadata !{metadata ![[msvcrt:[0-9]+]]}
 // LINUX: ![[msvcrt]] = metadata !{metadata !"-lmsvcrt"}
 
diff --git a/test/CodeGen/dllimport.c b/test/CodeGen/dllimport.c
index 485f6e2..32ee81f 100644
--- a/test/CodeGen/dllimport.c
+++ b/test/CodeGen/dllimport.c
@@ -53,7 +53,10 @@
 // Import function declaration.
 // CHECK-DAG: declare dllimport void @decl()
 __declspec(dllimport) void decl(void);
-USE(decl)
+
+// Initialize use_decl with the address of the thunk.
+// CHECK-DAG: @use_decl = global void ()* @decl
+void (*use_decl)(void) = &decl;
 
 // Import inline function.
 // CHECK-DAG: declare dllimport void @inlineFunc()
diff --git a/test/CodeGen/dwarf-version.c b/test/CodeGen/dwarf-version.c
index 6c0f097..0c67b4f 100644
--- a/test/CodeGen/dwarf-version.c
+++ b/test/CodeGen/dwarf-version.c
@@ -1,14 +1,14 @@
-// RUN: %clang -target x86_64-linux-gnu -gdwarf-2 -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang -target x86_64-linux-gnu -gdwarf-2 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
 // RUN: %clang -target x86_64-linux-gnu -gdwarf-3 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER3
 // RUN: %clang -target x86_64-linux-gnu -gdwarf-4 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4
-// RUN: %clang -target x86_64-linux-gnu -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=LINUX
-// RUN: %clang -target x86_64-apple-darwin -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DARWIN
+// RUN: %clang -target x86_64-linux-gnu -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4
+// RUN: %clang -target x86_64-apple-darwin -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
+// RUN: %clang -target powerpc-unknown-openbsd -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
+// RUN: %clang -target powerpc-unknown-freebsd -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
 int main (void) {
   return 0;
 }
 
-// CHECK: metadata !{i32 2, metadata !"Dwarf Version", i32 2}
+// VER2: metadata !{i32 2, metadata !"Dwarf Version", i32 2}
 // VER3: metadata !{i32 2, metadata !"Dwarf Version", i32 3}
 // VER4: metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-// LINUX: metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-// DARWIN: metadata !{i32 2, metadata !"Dwarf Version", i32 2}
diff --git a/test/CodeGen/exceptions-seh.c b/test/CodeGen/exceptions-seh.c
index f7d24bd..0a82e37 100644
--- a/test/CodeGen/exceptions-seh.c
+++ b/test/CodeGen/exceptions-seh.c
@@ -7,6 +7,7 @@
   int myres = 0;
   __try {
     myres = numerator / denominator;
+    __leave;
   } __except (1) {
     return 0;
   }
diff --git a/test/CodeGen/indirect-goto.c b/test/CodeGen/indirect-goto.c
index 7a3d717..a3b45e4 100644
--- a/test/CodeGen/indirect-goto.c
+++ b/test/CodeGen/indirect-goto.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o - %s | grep "ret i32 2520"
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O3 -emit-llvm -o - %s | grep "ret i32 2520"
 
 static int foo(unsigned i) {
   void *addrs[] = { &&L1, &&L2, &&L3, &&L4, &&L5 };
diff --git a/test/CodeGen/main-file-name.c b/test/CodeGen/main-file-name.c
deleted file mode 100644
index 83e2fe3..0000000
--- a/test/CodeGen/main-file-name.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -o - %s -main-file-name some.name | FileCheck -check-prefix NAMED %s
-
-// CHECK: ; ModuleID = '{{.*}}main-file-name.c'
-// NAMED: ; ModuleID = 'some.name'
-
diff --git a/test/CodeGen/mips-count-builtins.c b/test/CodeGen/mips-count-builtins.c
new file mode 100644
index 0000000..7c9a257
--- /dev/null
+++ b/test/CodeGen/mips-count-builtins.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -triple mips-unknown-linux-gnu -emit-llvm -o - | FileCheck %s
+//
+// Test that the ctlz and cttz builtins are defined for zero.
+// Based on count-builtin.c
+
+int leading, trailing, pop;
+
+void test_i16(short P) {
+  leading = __builtin_clzs(P);
+  trailing = __builtin_ctzs(P);
+
+// CHECK: @test_i16
+// CHECK: call i16 @llvm.ctlz.i16(i16 {{.*}}, i1 false)
+// CHECK: call i16 @llvm.cttz.i16(i16 {{.*}}, i1 false)
+}
+
+void test_i32(int P) {
+  leading = __builtin_clz(P);
+  trailing = __builtin_ctz(P);
+
+// CHECK: @test_i32
+// CHECK: call i32 @llvm.ctlz.i32(i32 {{.*}}, i1 false)
+// CHECK: call i32 @llvm.cttz.i32(i32 {{.*}}, i1 false)
+}
+
+void test_i64(float P) {
+  leading = __builtin_clzll(P);
+  trailing = __builtin_ctzll(P);
+// CHECK: @test_i64
+// CHECK: call i64 @llvm.ctlz.i64(i64 {{.*}}, i1 false)
+// CHECK: call i64 @llvm.cttz.i64(i64 {{.*}}, i1 false)
+}
diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c
index 69066aa..d6f6e2e 100644
--- a/test/CodeGen/ms-inline-asm-64.c
+++ b/test/CodeGen/ms-inline-asm-64.c
@@ -37,7 +37,9 @@
   foo.b = 2;
   __asm {
      lea ebx, foo
-     mov eax, [ebx].foo.a
+     {
+       mov eax, [ebx].foo.a
+     }
      mov [ebx].foo.b, ecx
   }
   return foo.b;
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index 6395e42..3b55b50 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -52,6 +52,11 @@
   __asm {
     int 0x2c ; } asm comments are fun! }{
   }
+  __asm {
+    {
+      int 0x2c ; } asm comments are fun! }{
+    }
+  }
   __asm {}
 // CHECK: t7
 // CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
@@ -73,8 +78,8 @@
 void t9() {
   __asm {
     push ebx
-    mov ebx, 0x07
-    pop ebx
+    { mov ebx, 0x07 }
+    __asm { pop ebx }
   }
 // CHECK: t9
 // CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
@@ -129,7 +134,7 @@
   unsigned i = 1, j = 2;
   __asm {
     .if 1
-    mov eax, i
+    { mov eax, i }
     .else
     mov ebx, j
     .endif
@@ -409,6 +414,7 @@
   __asm mov eax, 4 + 8 * -16
   __asm mov eax, 4 + 16 / -8
   __asm mov eax, (16 + 16) / -8
+  __asm mov eax, ~15
 // CHECK: t37
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$12", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$132", "~{eax},~{dirflag},~{fpsr},~{flags}"()
@@ -417,6 +423,7 @@
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967172", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967292", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967280", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t38() {
diff --git a/test/CodeGen/ms-intrinsics.c b/test/CodeGen/ms-intrinsics.c
new file mode 100644
index 0000000..fb0f62c
--- /dev/null
+++ b/test/CodeGen/ms-intrinsics.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple i686--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple thumbv7--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s
+
+void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) {
+  return _InterlockedExchangePointer(Target, Value);
+}
+
+// CHECK: define{{.*}}i8* @test_InterlockedExchangePointer(i8** %Target, i8* %Value){{.*}}{
+// CHECK:   %[[TARGET:[0-9]+]] = bitcast i8** %Target to i32*
+// CHECK:   %[[VALUE:[0-9]+]] = ptrtoint i8* %Value to i32
+// CHECK:   %[[EXCHANGE:[0-9]+]] = atomicrmw xchg i32* %[[TARGET]], i32 %[[VALUE]] seq_cst
+// CHECK:   %[[RESULT:[0-9]+]] = inttoptr i32 %[[EXCHANGE]] to i8*
+// CHECK:   ret i8* %[[RESULT]]
+// CHECK: }
+
+void *test_InterlockedCompareExchangePointer(void * volatile *Destination,
+                                             void *Exchange, void *Comparand) {
+  return _InterlockedCompareExchangePointer(Destination, Exchange, Comparand);
+}
+
+// CHECK: define{{.*}}i8* @test_InterlockedCompareExchangePointer(i8** %Destination, i8* %Exchange, i8* %Comparand){{.*}}{
+// CHECK:   %[[DEST:[0-9]+]] = bitcast i8** %Destination to i32*
+// CHECK:   %[[EXCHANGE:[0-9]+]] = ptrtoint i8* %Exchange to i32
+// CHECK:   %[[COMPARAND:[0-9]+]] = ptrtoint i8* %Comparand to i32
+// CHECK:   %[[XCHG:[0-9]+]] = cmpxchg volatile i32* %[[DEST:[0-9]+]], i32 %[[COMPARAND:[0-9]+]], i32 %[[EXCHANGE:[0-9]+]] seq_cst seq_cst
+// CHECK:   %[[EXTRACT:[0-9]+]] = extractvalue { i32, i1 } %[[XCHG]], 0
+// CHECK:   %[[RESULT:[0-9]+]] = inttoptr i32 %[[EXTRACT]] to i8*
+// CHECK:   ret i8* %[[RESULT:[0-9]+]]
+// CHECK: }
+
+long test_InterlockedExchange(long *Target, long Value) {
+  return _InterlockedExchange(Target, Value);
+}
+
+// CHECK: define{{.*}}i32 @test_InterlockedExchange(i32* %Target, i32 %Value){{.*}}{
+// CHECK:   %[[EXCHANGE:[0-9]+]] = atomicrmw xchg i32* %Target, i32 %Value seq_cst
+// CHECK:   ret i32 %[[EXCHANGE:[0-9]+]]
+// CHECK: }
diff --git a/test/CodeGen/named_reg_global.c b/test/CodeGen/named_reg_global.c
index 53f304d..8117dae 100644
--- a/test/CodeGen/named_reg_global.c
+++ b/test/CodeGen/named_reg_global.c
@@ -4,6 +4,13 @@
 
 // CHECK-NOT: @sp = common global
 register unsigned long current_stack_pointer asm("sp");
+struct p4_Thread {
+  struct {
+    int len;
+  } word;
+};
+// Testing pointer types as well
+register struct p4_Thread *p4TH asm("sp");
 
 // CHECK: define{{.*}} i[[bits:[0-9]+]] @get_stack_pointer_addr()
 // CHECK: [[ret:%[0-9]+]] = call i[[bits]] @llvm.read_register.i[[bits]](metadata !0)
@@ -22,5 +29,19 @@
 }
 // CHECK: declare{{.*}} void @llvm.write_register.i[[bits]](metadata, i[[bits]])
 
+// CHECK: define {{.*}}@fn1
+int fn1() {
+  return (*p4TH).word.len;
+}
+// CHECK: %[[regr:[0-9]+]] = call i[[bits]] @llvm.read_register.i[[bits]](metadata !0)
+// CHECK: inttoptr i[[bits]] %[[regr]] to %struct.p4_Thread*
+
+// CHECK: define {{.*}}@fn2
+void fn2(struct p4_Thread *val) {
+  p4TH = val;
+}
+// CHECK: %[[regw:[0-9]+]] = ptrtoint %struct.p4_Thread* %{{.*}} to i[[bits]]
+// CHECK: call void @llvm.write_register.i[[bits]](metadata !0, i[[bits]] %[[regw]])
+
 // CHECK: !llvm.named.register.sp = !{!0}
 // CHECK: !0 = metadata !{metadata !"sp"}
diff --git a/test/CodeGen/powerpc_types.c b/test/CodeGen/powerpc_types.c
index 8b2b156..b7d0f5d 100644
--- a/test/CodeGen/powerpc_types.c
+++ b/test/CodeGen/powerpc_types.c
@@ -1,4 +1,3 @@
-// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc-unknown-freebsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s
 
 #include <stdarg.h>
diff --git a/test/CodeGen/ppc64-align-struct.c b/test/CodeGen/ppc64-align-struct.c
new file mode 100644
index 0000000..272809f
--- /dev/null
+++ b/test/CodeGen/ppc64-align-struct.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+#include <stdarg.h>
+
+struct test1 { int x; int y; };
+struct test2 { int x; int y; } __attribute__((aligned (16)));
+struct test3 { int x; int y; } __attribute__((aligned (32)));
+struct test4 { int x; int y; int z; };
+
+// CHECK: define void @test1(i32 signext %x, %struct.test1* byval align 8 %y)
+void test1 (int x, struct test1 y)
+{
+}
+
+// CHECK: define void @test2(i32 signext %x, %struct.test2* byval align 16 %y)
+void test2 (int x, struct test2 y)
+{
+}
+
+// This case requires run-time realignment of the incoming struct
+// CHECK: define void @test3(i32 signext %x, %struct.test3* byval align 16)
+// CHECK: %y = alloca %struct.test3, align 32
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+void test3 (int x, struct test3 y)
+{
+}
+
+// CHECK: define void @test4(i32 signext %x, %struct.test4* byval align 8 %y)
+void test4 (int x, struct test4 y)
+{
+}
+
+// CHECK: define void @test1va(%struct.test1* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %ap.cur = load i8** %ap
+// CHECK: %ap.next = getelementptr i8* %ap.cur, i64 8
+// CHECK: store i8* %ap.next, i8** %ap
+// CHECK: bitcast i8* %ap.cur to %struct.test1*
+struct test1 test1va (int x, ...)
+{
+  struct test1 y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test1);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @test2va(%struct.test2* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %ap.cur = load i8** %ap
+// CHECK: %[[TMP0:[0-9]+]] = ptrtoint i8* %ap.cur to i64
+// CHECK: %[[TMP1:[0-9]+]] = add i64 %[[TMP0]], 15
+// CHECK: %[[TMP2:[0-9]+]] = and i64 %[[TMP1]], -16
+// CHECK: %ap.align = inttoptr i64 %[[TMP2]] to i8*
+// CHECK: %ap.next = getelementptr i8* %ap.align, i64 16
+// CHECK: store i8* %ap.next, i8** %ap
+// CHECK: bitcast i8* %ap.align to %struct.test2*
+struct test2 test2va (int x, ...)
+{
+  struct test2 y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test2);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @test3va(%struct.test3* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %ap.cur = load i8** %ap
+// CHECK: %[[TMP0:[0-9]+]] = ptrtoint i8* %ap.cur to i64
+// CHECK: %[[TMP1:[0-9]+]] = add i64 %[[TMP0]], 15
+// CHECK: %[[TMP2:[0-9]+]] = and i64 %[[TMP1]], -16
+// CHECK: %ap.align = inttoptr i64 %[[TMP2]] to i8*
+// CHECK: %ap.next = getelementptr i8* %ap.align, i64 32
+// CHECK: store i8* %ap.next, i8** %ap
+// CHECK: bitcast i8* %ap.align to %struct.test3*
+struct test3 test3va (int x, ...)
+{
+  struct test3 y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test3);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @test4va(%struct.test4* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %ap.cur = load i8** %ap
+// CHECK: %ap.next = getelementptr i8* %ap.cur, i64 16
+// CHECK: store i8* %ap.next, i8** %ap
+// CHECK: bitcast i8* %ap.cur to %struct.test4*
+struct test4 test4va (int x, ...)
+{
+  struct test4 y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test4);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @testva_longdouble(%struct.test_longdouble* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %ap.cur = load i8** %ap
+// CHECK: %ap.next = getelementptr i8* %ap.cur, i64 16
+// CHECK: store i8* %ap.next, i8** %ap
+// CHECK: bitcast i8* %ap.cur to %struct.test_longdouble*
+struct test_longdouble { long double x; };
+struct test_longdouble testva_longdouble (int x, ...)
+{
+  struct test_longdouble y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test_longdouble);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @testva_vector(%struct.test_vector* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %ap.cur = load i8** %ap
+// CHECK: %[[TMP0:[0-9]+]] = ptrtoint i8* %ap.cur to i64
+// CHECK: %[[TMP1:[0-9]+]] = add i64 %[[TMP0]], 15
+// CHECK: %[[TMP2:[0-9]+]] = and i64 %[[TMP1]], -16
+// CHECK: %ap.align = inttoptr i64 %[[TMP2]] to i8*
+// CHECK: %ap.next = getelementptr i8* %ap.align, i64 16
+// CHECK: store i8* %ap.next, i8** %ap
+// CHECK: bitcast i8* %ap.align to %struct.test_vector*
+struct test_vector { vector int x; };
+struct test_vector testva_vector (int x, ...)
+{
+  struct test_vector y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test_vector);
+  va_end(ap);
+  return y;
+}
+
diff --git a/test/CodeGen/ppc64-complex-parms.c b/test/CodeGen/ppc64-complex-parms.c
index ec56f9f..fe3025a 100644
--- a/test/CodeGen/ppc64-complex-parms.c
+++ b/test/CodeGen/ppc64-complex-parms.c
@@ -1,4 +1,3 @@
-// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 float crealf(_Complex float);
diff --git a/test/CodeGen/ppc64-vector.c b/test/CodeGen/ppc64-vector.c
new file mode 100644
index 0000000..3ff07a4
--- /dev/null
+++ b/test/CodeGen/ppc64-vector.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+typedef short v2i16 __attribute__((vector_size (4)));
+typedef short v3i16 __attribute__((vector_size (6)));
+typedef short v4i16 __attribute__((vector_size (8)));
+typedef short v6i16 __attribute__((vector_size (12)));
+typedef short v8i16 __attribute__((vector_size (16)));
+typedef short v16i16 __attribute__((vector_size (32)));
+
+struct v16i16 { v16i16 x; };
+
+// CHECK: define i32 @test_v2i16(i32 %x.coerce)
+v2i16 test_v2i16(v2i16 x)
+{
+  return x;
+}
+
+// CHECK: define i64 @test_v3i16(i64 %x.coerce)
+v3i16 test_v3i16(v3i16 x)
+{
+  return x;
+}
+
+// CHECK: define i64 @test_v4i16(i64 %x.coerce)
+v4i16 test_v4i16(v4i16 x)
+{
+  return x;
+}
+
+// CHECK: define <6 x i16> @test_v6i16(<6 x i16> %x)
+v6i16 test_v6i16(v6i16 x)
+{
+  return x;
+}
+
+// CHECK: define <8 x i16> @test_v8i16(<8 x i16> %x)
+v8i16 test_v8i16(v8i16 x)
+{
+  return x;
+}
+
+// CHECK: define void @test_v16i16(<16 x i16>* noalias sret %agg.result, <16 x i16>*)
+v16i16 test_v16i16(v16i16 x)
+{
+  return x;
+}
+
+// CHECK: define void @test_struct_v16i16(%struct.v16i16* noalias sret %agg.result, %struct.v16i16* byval align 16)
+struct v16i16 test_struct_v16i16(struct v16i16 x)
+{
+  return x;
+}
diff --git a/test/CodeGen/ppc64le-varargs-complex.c b/test/CodeGen/ppc64le-varargs-complex.c
new file mode 100644
index 0000000..b89f462
--- /dev/null
+++ b/test/CodeGen/ppc64le-varargs-complex.c
@@ -0,0 +1,69 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+#include <stdarg.h>
+
+void testva (int n, ...)
+{
+  va_list ap;
+
+  _Complex int i   = va_arg(ap, _Complex int);
+  // CHECK: %[[VAR40:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+  // CHECK-NEXT: %[[VAR41:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR40]], i64 16
+  // CHECK-NEXT: store i8* %[[VAR41]], i8** %[[VAR100]]
+  // CHECK-NEXT: %[[VAR1:[A-Za-z0-9.]+]] = ptrtoint i8* %[[VAR40]] to i64
+  // CHECK-NEXT: %[[VAR3:[A-Za-z0-9.]+]] = add i64 %[[VAR1]], 8
+  // CHECK-NEXT: %[[VAR4:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR1]] to i32*
+  // CHECK-NEXT: %[[VAR5:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR3]] to i32*
+  // CHECK-NEXT: %[[VAR6:[A-Za-z0-9.]+]] = load i32* %[[VAR4]]
+  // CHECK-NEXT: %[[VAR7:[A-Za-z0-9.]+]] = load i32* %[[VAR5]]
+  // CHECK-NEXT: %[[VAR8:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }* %[[VAR0:[A-Za-z0-9.]+]], i32 0, i32 0
+  // CHECK-NEXT: %[[VAR9:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }* %[[VAR0]], i32 0, i32 1
+  // CHECK-NEXT: store i32 %[[VAR6]], i32* %[[VAR8]]
+  // CHECK-NEXT: store i32 %[[VAR7]], i32* %[[VAR9]]
+
+  _Complex short s = va_arg(ap, _Complex short);
+  // CHECK: %[[VAR50:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+  // CHECK-NEXT: %[[VAR51:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR50]], i64 16
+  // CHECK-NEXT: store i8* %[[VAR51]], i8** %[[VAR100]]
+  // CHECK: %[[VAR11:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+  // CHECK-NEXT: %[[VAR13:[A-Za-z0-9.]+]] = add i64 %[[VAR11]], 8
+  // CHECK-NEXT: %[[VAR14:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR11]] to i16*
+  // CHECK-NEXT: %[[VAR15:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR13]] to i16*
+  // CHECK-NEXT: %[[VAR16:[A-Za-z0-9.]+]] = load i16* %[[VAR14]]
+  // CHECK-NEXT: %[[VAR17:[A-Za-z0-9.]+]] = load i16* %[[VAR15]]
+  // CHECK-NEXT: %[[VAR18:[A-Za-z0-9.]+]] = getelementptr inbounds { i16, i16 }* %[[VAR10:[A-Za-z0-9.]+]], i32 0, i32 0
+  // CHECK-NEXT: %[[VAR19:[A-Za-z0-9.]+]] = getelementptr inbounds { i16, i16 }* %[[VAR10]], i32 0, i32 1
+  // CHECK-NEXT: store i16 %[[VAR16]], i16* %[[VAR18]]
+  // CHECK-NEXT: store i16 %[[VAR17]], i16* %[[VAR19]]
+
+  _Complex char c  = va_arg(ap, _Complex char);
+  // CHECK: %[[VAR60:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+  // CHECK-NEXT: %[[VAR61:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR60]], i64 16
+  // CHECK-NEXT: store i8* %[[VAR61]], i8** %[[VAR100]]
+  // CHECK: %[[VAR21:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+  // CHECK-NEXT: %[[VAR23:[A-Za-z0-9.]+]] = add i64 %[[VAR21]], 8
+  // CHECK-NEXT: %[[VAR24:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR21]] to i8*
+  // CHECK-NEXT: %[[VAR25:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR23]] to i8*
+  // CHECK-NEXT: %[[VAR26:[A-Za-z0-9.]+]] = load i8* %[[VAR24]]
+  // CHECK-NEXT: %[[VAR27:[A-Za-z0-9.]+]] = load i8* %[[VAR25]]
+  // CHECK-NEXT: %[[VAR28:[A-Za-z0-9.]+]] = getelementptr inbounds { i8, i8 }* %[[VAR20:[A-Za-z0-9.]+]], i32 0, i32 0
+  // CHECK-NEXT: %[[VAR29:[A-Za-z0-9.]+]] = getelementptr inbounds { i8, i8 }* %[[VAR20]], i32 0, i32 1
+  // CHECK-NEXT: store i8 %[[VAR26]], i8* %[[VAR28]]
+  // CHECK-NEXT: store i8 %[[VAR27]], i8* %[[VAR29]]
+
+  _Complex float f = va_arg(ap, _Complex float);
+  // CHECK: %[[VAR70:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+  // CHECK-NEXT: %[[VAR71:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR70]], i64 16
+  // CHECK-NEXT: store i8* %[[VAR71]], i8** %[[VAR100]]
+  // CHECK: %[[VAR31:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+  // CHECK-NEXT: %[[VAR33:[A-Za-z0-9.]+]] = add i64 %[[VAR31]], 8
+  // CHECK-NEXT: %[[VAR34:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR31]] to float*
+  // CHECK-NEXT: %[[VAR35:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR33]] to float*
+  // CHECK-NEXT: %[[VAR36:[A-Za-z0-9.]+]] = load float* %[[VAR34]]
+  // CHECK-NEXT: %[[VAR37:[A-Za-z0-9.]+]] = load float* %[[VAR35]]
+  // CHECK-NEXT: %[[VAR38:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }* %[[VAR30:[A-Za-z0-9.]+]], i32 0, i32 0
+  // CHECK-NEXT: %[[VAR39:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }* %[[VAR30]], i32 0, i32 1
+  // CHECK-NEXT: store float %[[VAR36]], float* %[[VAR38]]
+  // CHECK-NEXT: store float %[[VAR37]], float* %[[VAR39]]
+}
diff --git a/test/CodeGen/pr19841.cpp b/test/CodeGen/pr19841.cpp
index 1357be2..8fef683 100644
--- a/test/CodeGen/pr19841.cpp
+++ b/test/CodeGen/pr19841.cpp
@@ -12,6 +12,7 @@
   unsigned char _highlightColorTableVGA[];
   static const unsigned char b[];
 };
+// CHECK: [[Common_A_b:@[^ ]+]] = constant [1 x i8] zeroinitializer
 class B {
 public:
   Common::RenderMode _configRenderMode;
@@ -22,7 +23,7 @@
       ? b
       : _highlightColorTableVGA;
 // Make sure the PHI value is casted correctly to the PHI type
-// CHECK: %{{.*}} = phi [0 x i8]* [ bitcast ([1 x i8]* @_ZN6Common1A1bE to [0 x i8]*), %{{.*}} ], [ %{{.*}}, %{{.*}} ]
+// CHECK: %{{.*}} = phi [0 x i8]* [ bitcast ([1 x i8]* [[Common_A_b]] to [0 x i8]*), %{{.*}} ], [ %{{.*}}, %{{.*}} ]
 }
 const unsigned char A::b[] = { 0 };
 }
diff --git a/test/CodeGen/pragma-comment.c b/test/CodeGen/pragma-comment.c
index 30bf7b7..73cc548 100644
--- a/test/CodeGen/pragma-comment.c
+++ b/test/CodeGen/pragma-comment.c
@@ -9,8 +9,8 @@
 #define BAR "2"
 #pragma comment(linker," /bar=" BAR)
 
-// CHECK: !llvm.module.flags = !{!0}
-// CHECK: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
+// CHECK: !llvm.module.flags = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
 // CHECK: ![[link_opts]] = metadata !{metadata ![[msvcrt:[0-9]+]], metadata ![[kernel32:[0-9]+]], metadata ![[USER32:[0-9]+]], metadata ![[bar:[0-9]+]]}
 // CHECK: ![[msvcrt]] = metadata !{metadata !"/DEFAULTLIB:msvcrt.lib"}
 // CHECK: ![[kernel32]] = metadata !{metadata !"/DEFAULTLIB:kernel32.lib"}
diff --git a/test/CodeGen/pragma-detect_mismatch.c b/test/CodeGen/pragma-detect_mismatch.c
index 86cc6d8..b223a61 100644
--- a/test/CodeGen/pragma-detect_mismatch.c
+++ b/test/CodeGen/pragma-detect_mismatch.c
@@ -5,8 +5,8 @@
 #define BAR "2"

 #pragma detect_mismatch("test2", BAR)

 

-// CHECK: !llvm.module.flags = !{!0}

-// CHECK: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}

+// CHECK: !llvm.module.flags = !{{{.*}}}

+// CHECK: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}

 // CHECK: ![[link_opts]] = metadata !{metadata ![[test:[0-9]+]], metadata ![[test2:[0-9]+]]}

 // CHECK: ![[test]] = metadata !{metadata !"/FAILIFMISMATCH:\22test=1\22"}

 // CHECK: ![[test2]] = metadata !{metadata !"/FAILIFMISMATCH:\22test2=2\22"}

diff --git a/test/CodeGen/pragma-loop.cpp b/test/CodeGen/pragma-loop.cpp
new file mode 100644
index 0000000..447a709
--- /dev/null
+++ b/test/CodeGen/pragma-loop.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify while loop is recognized after sequence of pragma clang loop directives.
+void while_test(int *List, int Length) {
+  // CHECK: define {{.*}} @_Z10while_test
+  int i = 0;
+
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave_count(4)
+#pragma clang loop vectorize_width(4)
+#pragma clang loop unroll(enable)
+  while (i < Length) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+    List[i] = i * 2;
+    i++;
+  }
+}
+
+// Verify do loop is recognized after multi-option pragma clang loop directive.
+void do_test(int *List, int Length) {
+  int i = 0;
+
+#pragma clang loop vectorize_width(8) interleave_count(4) unroll(disable)
+  do {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+    List[i] = i * 2;
+    i++;
+  } while (i < Length);
+}
+
+// Verify for loop is recognized after sequence of pragma clang loop directives.
+void for_test(int *List, int Length) {
+#pragma clang loop interleave(enable)
+#pragma clang loop interleave_count(4)
+#pragma clang loop unroll_count(8)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+    List[i] = i * 2;
+  }
+}
+
+// Verify c++11 for range loop is recognized after
+// sequence of pragma clang loop directives.
+void for_range_test() {
+  double List[100];
+
+#pragma clang loop vectorize_width(2) interleave_count(2)
+  for (int i : List) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+    List[i] = i;
+  }
+}
+
+// Verify disable pragma clang loop directive generates correct metadata
+void disable_test(int *List, int Length) {
+#pragma clang loop vectorize(disable) unroll(disable)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
+    List[i] = i * 2;
+  }
+}
+
+#define VECWIDTH 2
+#define INTCOUNT 2
+#define UNROLLCOUNT 8
+
+// Verify defines are correctly resolved in pragma clang loop directive
+void for_define_test(int *List, int Length, int Value) {
+#pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
+#pragma clang loop unroll_count(UNROLLCOUNT)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
+    List[i] = i * Value;
+  }
+}
+
+// Verify metadata is generated when template is used.
+template <typename A>
+void for_template_test(A *List, int Length, A Value) {
+
+#pragma clang loop vectorize_width(8) interleave_count(8) unroll_count(8)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+    List[i] = i * Value;
+  }
+}
+
+// Verify define is resolved correctly when template is used.
+template <typename A>
+void for_template_define_test(A *List, int Length, A Value) {
+#pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
+#pragma clang loop unroll_count(UNROLLCOUNT)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_8:.*]]
+    List[i] = i * Value;
+  }
+}
+
+#undef VECWIDTH
+#undef INTCOUNT
+#undef UNROLLCOUNT
+
+// Use templates defined above. Test verifies metadata is generated correctly.
+void template_test(double *List, int Length) {
+  double Value = 10;
+
+  for_template_test<double>(List, Length, Value);
+  for_template_define_test<double>(List, Length, Value);
+}
+
+// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLLENABLE_1:.*]], metadata ![[WIDTH_4:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[INTENABLE_1:.*]]}
+// CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 true}
+// CHECK: ![[WIDTH_4]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 4}
+// CHECK: ![[INTERLEAVE_4]] = metadata !{metadata !"llvm.loop.vectorize.unroll", i32 4}
+// CHECK: ![[INTENABLE_1]] = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
+// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[WIDTH_8:.*]]}
+// CHECK: ![[UNROLLENABLE_0]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 false}
+// CHECK: ![[WIDTH_8]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 8}
+// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[ENABLE_1:.*]]}
+// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loop.unroll.count", i32 8}
+// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
+// CHECK: ![[INTERLEAVE_2]] = metadata !{metadata !"llvm.loop.vectorize.unroll", i32 2}
+// CHECK: ![[WIDTH_2]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 2}
+// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[WIDTH_1:.*]]}
+// CHECK: ![[WIDTH_1]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
+// CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
+// CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_8:.*]], metadata ![[WIDTH_8:.*]]}
+// CHECK: ![[INTERLEAVE_8]] = metadata !{metadata !"llvm.loop.vectorize.unroll", i32 8}
+// CHECK: ![[LOOP_8]] = metadata !{metadata ![[LOOP_8]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
diff --git a/test/CodeGen/sanitize-init-order.cpp b/test/CodeGen/sanitize-init-order.cpp
index 3e94620..8c662db 100644
--- a/test/CodeGen/sanitize-init-order.cpp
+++ b/test/CodeGen/sanitize-init-order.cpp
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -fsanitize=address,init-order -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - %s | FileCheck %s
+
+// Test blacklist functionality.
+// RUN: echo "global-init-src:%s" > %t-file.blacklist
+// RUN: echo "global-init-type:struct.PODWithCtorAndDtor" > %t-type.blacklist
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t-file.blacklist -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t-type.blacklist -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST
+// REQUIRES: shell
 
 struct PODStruct {
   int x;
@@ -20,5 +27,12 @@
 
 // Check that ASan init-order checking ignores structs with trivial default
 // constructor.
-// CHECK: !llvm.asan.dynamically_initialized_globals = !{[[GLOB:![0-9]+]]}
-// CHECK: [[GLOB]] = metadata !{%struct.PODWithCtorAndDtor
+// CHECK: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]]}
+// CHECK: ![[GLOB_1]] = metadata !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
+// CHECK: ![[GLOB_2]] = metadata !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
+// CHECK: ![[GLOB_3]] = metadata !{%struct.PODWithCtorAndDtor* {{.*}}, i1 true, i1 false}
+
+// BLACKLIST: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]]}
+// BLACKLIST: ![[GLOB_1]] = metadata !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
+// BLACKLIST: ![[GLOB_2]] = metadata !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
+// BLACKLIST: ![[GLOB_3]] = metadata !{%struct.PODWithCtorAndDtor* {{.*}}, i1 false, i1 false}
diff --git a/test/CodeGen/sanitize-use-after-scope.c b/test/CodeGen/sanitize-use-after-scope.c
deleted file mode 100644
index 8f92038..0000000
--- a/test/CodeGen/sanitize-use-after-scope.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address,use-after-scope %s \
-// RUN:     | FileCheck %s -check-prefix=USE-AFTER-SCOPE
-// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address %s \
-// RUN:     | FileCheck %s -check-prefix=ADDRESS-ONLY
-
-extern int bar(char *A, int n);
-
-// ADDRESS-ONLY-NOT: @llvm.lifetime.start
-int foo (int n) {
-  if (n) {
-    // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 10, i8* {{.*}})
-    char A[10];
-    return bar(A, 1);
-    // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 10, i8* {{.*}})
-  } else {
-    // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 20, i8* {{.*}})
-    char A[20];
-    return bar(A, 2);
-    // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 20, i8* {{.*}})
-  }
-}
-
diff --git a/test/CodeGen/sse-builtins-dbg.c b/test/CodeGen/sse-builtins-dbg.c
new file mode 100644
index 0000000..8190744
--- /dev/null
+++ b/test/CodeGen/sse-builtins-dbg.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-apple-macosx10.8.0 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s
+
+// Test that intrinsic calls inlined from _mm_* wrappers have debug metadata.
+
+#include <xmmintrin.h>
+
+__m128 test_rsqrt_ss(__m128 x) {
+  // CHECK: define {{.*}} @test_rsqrt_ss
+  // CHECK: call <4 x float> @llvm.x86.sse.rsqrt.ss({{.*}}, !dbg !{{.*}}
+  // CHECK: ret <4 x float>
+  return _mm_rsqrt_ss(x);
+}
diff --git a/test/CodeGen/sse-builtins.c b/test/CodeGen/sse-builtins.c
index 874cf6d..238454b 100644
--- a/test/CodeGen/sse-builtins.c
+++ b/test/CodeGen/sse-builtins.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -ffreestanding -triple x86_64-apple-macosx10.8.0 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-apple-macosx10.8.0 -target-feature +sse4.1 -emit-llvm %s -o - | FileCheck %s
 
 #include <xmmintrin.h>
 #include <emmintrin.h>
@@ -64,7 +64,7 @@
 
 void test_store_ss(__m128 x, void* y) {
   // CHECK-LABEL: define void @test_store_ss
-  // CHECK: store {{.*}} float* {{.*}}, align 1,
+  // CHECK: store {{.*}} float* {{.*}}, align 1{{$}}
   _mm_store_ss(y, x);
 }
 
diff --git a/test/CodeGen/variadic-gpfp-x86.c b/test/CodeGen/variadic-gpfp-x86.c
new file mode 100644
index 0000000..735c4be
--- /dev/null
+++ b/test/CodeGen/variadic-gpfp-x86.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+struct Bar {
+ float f1;
+ float f2;
+ unsigned u;
+};
+
+struct Bar foo(__builtin_va_list ap) {
+  return __builtin_va_arg(ap, struct Bar);
+// CHECK: [[FPOP:%.*]] = getelementptr inbounds %struct.__va_list_tag* {{.*}}, i32 0, i32 1
+// CHECK: [[FPO:%.*]] = load i32* [[FPOP]]
+// CHECK: [[FPVEC:%.*]] = getelementptr i8* {{.*}}, i32 [[FPO]]
+// CHECK: bitcast i8* [[FPVEC]] to <2 x float>*
+}
diff --git a/test/CodeGen/windows-itanium.c b/test/CodeGen/windows-itanium.c
new file mode 100644
index 0000000..7f0e7b1
--- /dev/null
+++ b/test/CodeGen/windows-itanium.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple i686-windows-itanium -emit-llvm %s -o - \
+// RUN:    | FileCheck %s -check-prefix CHECK-C -check-prefix CHECK
+
+// RUN: %clang_cc1 -triple i686-windows-itanium -emit-llvm -x c++ %s -o - \
+// RUN:    | FileCheck %s -check-prefix CHECK-CXX -check-prefix CHECK
+
+int function() {
+  return 32;
+}
+
+// CHECK-C: define i32 @function() {{.*}} {
+// CHECK-CXX: define i32 @_Z8functionv() {{.*}} {
+// CHECK:   ret i32 32
+// CHECK: }
+
diff --git a/test/CodeGen/x86-64-inline-asm.c b/test/CodeGen/x86-64-inline-asm.c
new file mode 100644
index 0000000..fefbf76
--- /dev/null
+++ b/test/CodeGen/x86-64-inline-asm.c
@@ -0,0 +1,12 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -DWARN -verify
+// RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -Werror -verify
+void f() {
+  asm("movaps %xmm3, (%esi, 2)");
+// expected-note@1 {{instantiated into assembly here}}
+#ifdef WARN
+// expected-warning@-3 {{scale factor without index register is ignored}}
+#else
+// expected-error@-5 {{scale factor without index register is ignored}}
+#endif
+}
diff --git a/test/CodeGen/x86_64-atomic-128.c b/test/CodeGen/x86_64-atomic-128.c
new file mode 100644
index 0000000..2069e45
--- /dev/null
+++ b/test/CodeGen/x86_64-atomic-128.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -target-cpu core2 %s -S -emit-llvm -o - | FileCheck %s
+
+// All atomics up to 16 bytes should be emitted inline on x86_64. The
+// backend can reform __sync_whatever calls if necessary (e.g. the CPU
+// doesn't have cmpxchg16b).
+
+__int128 test_sync_call(__int128 *addr, __int128 val) {
+  // CHECK-LABEL: @test_sync_call
+  // CHECK: atomicrmw add i128
+  return __sync_fetch_and_add(addr, val);
+}
+
+__int128 test_c11_call(_Atomic __int128 *addr, __int128 val) {
+  // CHECK-LABEL: @test_c11_call
+  // CHECK: atomicrmw sub
+  return __c11_atomic_fetch_sub(addr, val, 0);
+}
+
+__int128 test_atomic_call(__int128 *addr, __int128 val) {
+  // CHECK-LABEL: @test_atomic_call
+  // CHECK: atomicrmw or
+  return __atomic_fetch_or(addr, val, 0);
+}
+
+__int128 test_expression(_Atomic __int128 *addr) {
+  // CHECK-LABEL: @test_expression
+  // CHECK: atomicrmw and
+  *addr &= 1;
+}
diff --git a/test/CodeGen/xcore-stringtype.c b/test/CodeGen/xcore-stringtype.c
index 0c4e75d..25589d5 100644
--- a/test/CodeGen/xcore-stringtype.c
+++ b/test/CodeGen/xcore-stringtype.c
@@ -9,13 +9,13 @@
 // Please see 'Tools Development Guide' section 2.16.2 for format details:
 // <https://www.xmos.com/download/public/Tools-Development-Guide%28X9114A%29.pdf>
 
-// CHECK: !xcore.typestrings = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10,
-// CHECK: !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23,
-// CHECK: !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34}
+// CHECK: !xcore.typestrings = !{!1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11,
+// CHECK: !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25,
+// CHECK: !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38}
 
 
 // test BuiltinType
-// CHECK: !0 = metadata !{void (i1, i8, i8, i8, i16, i16, i16, i32, i32, i32,
+// CHECK: !1 = metadata !{void (i1, i8, i8, i8, i16, i16, i16, i32, i32, i32,
 // CHECK:      i32, i32, i32, i64, i64, i64, float, double, double)*
 // CHECK:      @builtinType, metadata !"f{0}(b,uc,uc,sc,ss,us,ss,si,ui,si,sl,
 // CHECK:      ul,sl,sll,ull,sll,ft,d,ld)"}
@@ -28,14 +28,14 @@
 
 
 // test FunctionType & Qualifiers
-// CHECK: !1 = metadata !{void ()* @gI, metadata !"f{0}()"}
-// CHECK: !2 = metadata !{void (...)* @eI, metadata !"f{0}()"}
-// CHECK: !3 = metadata !{void ()* @gV, metadata !"f{0}(0)"}
-// CHECK: !4 = metadata !{void ()* @eV, metadata !"f{0}(0)"}
-// CHECK: !5 = metadata !{void (i32, ...)* @gVA, metadata !"f{0}(si,va)"}
-// CHECK: !6 = metadata !{void (i32, ...)* @eVA, metadata !"f{0}(si,va)"}
-// CHECK: !7 = metadata !{i32* (i32*)* @gQ, metadata !"f{crv:p(cv:si)}(p(cv:si))"}
-// CHECK: !8 = metadata !{i32* (i32*)* @eQ, metadata !"f{crv:p(cv:si)}(p(cv:si))"}
+// CHECK: !2 = metadata !{void ()* @gI, metadata !"f{0}()"}
+// CHECK: !3 = metadata !{void (...)* @eI, metadata !"f{0}()"}
+// CHECK: !4 = metadata !{void ()* @gV, metadata !"f{0}(0)"}
+// CHECK: !5 = metadata !{void ()* @eV, metadata !"f{0}(0)"}
+// CHECK: !6 = metadata !{void (i32, ...)* @gVA, metadata !"f{0}(si,va)"}
+// CHECK: !7 = metadata !{void (i32, ...)* @eVA, metadata !"f{0}(si,va)"}
+// CHECK: !8 = metadata !{i32* (i32*)* @gQ, metadata !"f{crv:p(cv:si)}(p(cv:si))"}
+// CHECK: !9 = metadata !{i32* (i32*)* @eQ, metadata !"f{crv:p(cv:si)}(p(cv:si))"}
 extern void eI();
 void gI() {eI();};
 extern void eV(void);
@@ -49,49 +49,48 @@
 
 
 // test PointerType
-// CHECK: !9 = metadata !{i32* (i32*, i32* (i32*)*)*
-// CHECK:      @pointerType, metadata !"f{p(si)}(p(si),p(f{p(si)}(p(si))))"}
-// CHECK: !10 = metadata !{i32** @EP, metadata !"p(si)"}
-// CHECK: !11 = metadata !{i32** @GP, metadata !"p(si)"}
+// CHECK: !10 = metadata !{i32* (i32*, i32* (i32*)*)*
+// CHECK:       @pointerType, metadata !"f{p(si)}(p(si),p(f{p(si)}(p(si))))"}
+// CHECK: !11 = metadata !{i32** @EP, metadata !"p(si)"}
+// CHECK: !12 = metadata !{i32** @GP, metadata !"p(si)"}
 extern int* EP;
 int* GP;
 int* pointerType(int *I, int * (*FP)(int *)) {
   return I? EP : GP;
 }
 
-
 // test ArrayType
-// CHECK: !12 = metadata !{[2 x i32]* (i32*, i32*, [2 x i32]*, [2 x i32]*, i32*)*
-// CHECK:       @arrayType, metadata !"f{p(a(2:si))}(p(si),p(si),p(a(2:si)),
+// CHECK: !13 = metadata !{[2 x i32]* (i32*, i32*, [2 x i32]*, [2 x i32]*, i32*)*
+// CHECK:       @arrayType, metadata !"f{p(a(2:si))}(p(si),p(cv:si),p(a(2:si)),
 // CHECK:       p(a(2:si)),p(si))"}
-// CHECK: !13 = metadata !{[0 x i32]* @EA1, metadata !"a(*:si)"}
-// CHECK: !14 = metadata !{[2 x i32]* @EA2, metadata !"a(2:si)"}
-// CHECK: !15 = metadata !{[0 x [2 x i32]]* @EA3, metadata !"a(*:a(2:si))"}
-// CHECK: !16 = metadata !{[3 x [2 x i32]]* @EA4, metadata !"a(3:a(2:si))"}
-// CHECK: !17 = metadata !{[2 x i32]* @GA1, metadata !"a(2:si)"}
-// CHECK: !18 = metadata !{void ([2 x i32]*)* @arrayTypeVariable1,
+// CHECK: !14 = metadata !{[0 x i32]* @EA1, metadata !"a(*:cv:si)"}
+// CHECK: !15 = metadata !{[2 x i32]* @EA2, metadata !"a(2:si)"}
+// CHECK: !16 = metadata !{[0 x [2 x i32]]* @EA3, metadata !"a(*:a(2:si))"}
+// CHECK: !17 = metadata !{[3 x [2 x i32]]* @EA4, metadata !"a(3:a(2:si))"}
+// CHECK: !18 = metadata !{[2 x i32]* @GA1, metadata !"a(2:cv:si)"}
+// CHECK: !19 = metadata !{void ([2 x i32]*)* @arrayTypeVariable1,
 // CHECK:       metadata !"f{0}(p(a(2:si)))"}
-// CHECK: !19 = metadata !{void (void ([2 x i32]*)*)* @arrayTypeVariable2,
+// CHECK: !20 = metadata !{void (void ([2 x i32]*)*)* @arrayTypeVariable2,
 // CHECK:       metadata !"f{0}(p(f{0}(p(a(2:si)))))"}
-// CHECK: !20 = metadata !{[3 x [2 x i32]]* @GA2, metadata !"a(3:a(2:si))"}
-extern int EA1[];
+// CHECK: !21 = metadata !{[3 x [2 x i32]]* @GA2, metadata !"a(3:a(2:si))"}
+extern int GA2[3][2];
+extern const volatile int EA1[];
 extern int EA2[2];
 extern int EA3[][2];
 extern int EA4[3][2];
-int GA1[2];
-int GA2[3][2];
+const volatile int GA1[2];
 extern void arrayTypeVariable1(int[*][2]);
 extern void arrayTypeVariable2( void(*fp)(int[*][2]) );
 extern void arrayTypeVariable3(int[3][*]);                // not supported
 extern void arrayTypeVariable4( void(*fp)(int[3][*]) );   // not supported
 typedef int RetType[2];
-RetType* arrayType(int A1[], int A2[2], int A3[][2], int A4[3][2],
-                   int A5[const volatile restrict static 2]) {
-  if (A1) return &EA1;
+RetType* arrayType(int A1[], int const volatile A2[2], int A3[][2],
+                   int A4[3][2], int A5[const volatile restrict static 2]) {
+  if (A1) EA2[0] = EA1[0];
   if (A2) return &EA2;
   if (A3) return EA3;
   if (A4) return EA4;
-  if (A5) return &GA1;
+  if (A5) EA2[0] = GA1[0];
   arrayTypeVariable1(EA4);
   arrayTypeVariable2(arrayTypeVariable1);
   arrayTypeVariable3(EA4);
@@ -101,16 +100,16 @@
 
 
 // test StructureType
-// CHECK: !21 = metadata !{void (%struct.S1*)* @structureType1, metadata
+// CHECK: !22 = metadata !{void (%struct.S1*)* @structureType1, metadata
 // CHECK:       !"f{0}(s(S1){m(ps2){p(s(S2){m(ps3){p(s(S3){m(s1){s(S1){}}})}})}})"}
-// CHECK: !22 = metadata !{void (%struct.S2*)* @structureType2, metadata
+// CHECK: !23 = metadata !{void (%struct.S2*)* @structureType2, metadata
 // CHECK:       !"f{0}(s(S2){m(ps3){p(s(S3){m(s1){s(S1){m(ps2){p(s(S2){})}}}})}})"}
-// CHECK: !23 = metadata !{void (%struct.S3*)* @structureType3, metadata
+// CHECK: !24 = metadata !{void (%struct.S3*)* @structureType3, metadata
 // CHECK:       !"f{0}(s(S3){m(s1){s(S1){m(ps2){p(s(S2){m(ps3){p(s(S3){})}})}}}})"}
-// CHECK: !24 = metadata !{void (%struct.S4*)* @structureType4, metadata
+// CHECK: !25 = metadata !{void (%struct.S4*)* @structureType4, metadata
 // CHECK:       !"f{0}(s(S4){m(s1){s(S1){m(ps2){p(s(S2){m(ps3){p(s(S3){m(s1){s(S1){}}})}})}}}})"}
-// CHECK: !25 = metadata !{%struct.anon* @StructAnon, metadata !"s(){m(A){si}}"}
-// CHECK: !26 = metadata !{i32 (%struct.SB*)* @structureTypeB, metadata
+// CHECK: !26 = metadata !{%struct.anon* @StructAnon, metadata !"s(){m(A){si}}"}
+// CHECK: !27 = metadata !{i32 (%struct.SB*)* @structureTypeB, metadata
 // CHECK:       !"f{si}(s(SB){m(){b(4:si)},m(){b(2:si)},m(N4){b(4:si)},
 // CHECK:       m(N2){b(2:si)},m(){b(4:ui)},m(){b(4:si)},m(){b(4:c:si)},
 // CHECK:       m(){b(4:c:si)},m(){b(4:cv:si)}})"}
@@ -131,16 +130,16 @@
 
 
 // test UnionType
-// CHECK: !27 = metadata !{void (%union.U1*)* @unionType1, metadata
+// CHECK: !28 = metadata !{void (%union.U1*)* @unionType1, metadata
 // CHECK:       !"f{0}(u(U1){m(pu2){p(u(U2){m(pu3){p(u(U3){m(u1){u(U1){}}})}})}})"}
-// CHECK: !28 = metadata !{void (%union.U2*)* @unionType2, metadata
+// CHECK: !29 = metadata !{void (%union.U2*)* @unionType2, metadata
 // CHECK:       !"f{0}(u(U2){m(pu3){p(u(U3){m(u1){u(U1){m(pu2){p(u(U2){})}}}})}})"}
-// CHECK: !29 = metadata !{void (%union.U3*)* @unionType3, metadata
+// CHECK: !30 = metadata !{void (%union.U3*)* @unionType3, metadata
 // CHECK:       !"f{0}(u(U3){m(u1){u(U1){m(pu2){p(u(U2){m(pu3){p(u(U3){})}})}}}})"}
-// CHECK: !30 = metadata !{void (%union.U4*)* @unionType4, metadata
+// CHECK: !31 = metadata !{void (%union.U4*)* @unionType4, metadata
 // CHECK:       !"f{0}(u(U4){m(u1){u(U1){m(pu2){p(u(U2){m(pu3){p(u(U3){m(u1){u(U1){}}})}})}}}})"}
-// CHECK: !31 = metadata !{%union.anon* @UnionAnon, metadata !"u(){m(A){si}}"}
-// CHECK: !32 = metadata !{i32 (%union.UB*)* @unionTypeB, metadata
+// CHECK: !32 = metadata !{%union.anon* @UnionAnon, metadata !"u(){m(A){si}}"}
+// CHECK: !33 = metadata !{i32 (%union.UB*)* @unionTypeB, metadata
 // CHECK:       !"f{si}(u(UB){m(N2){b(2:si)},m(N4){b(4:si)},m(){b(2:si)},
 // CHECK:       m(){b(4:c:si)},m(){b(4:c:si)},m(){b(4:cv:si)},m(){b(4:si)},
 // CHECK:       m(){b(4:si)},m(){b(4:ui)}})"}
@@ -161,9 +160,20 @@
 
 
 // test EnumType
-// CHECK: !33 = metadata !{i32* @EnumAnon, metadata !"e(){m(EA){3}}"}
-// CHECK: !34 = metadata !{i32 (i32)* @enumType, metadata
+// CHECK: !34 = metadata !{i32* @EnumAnon, metadata !"e(){m(EA){3}}"}
+// CHECK: !35 = metadata !{i32 (i32)* @enumType, metadata
 // CHECK:       !"f{si}(e(E){m(A){7},m(B){6},m(C){5},m(D){0}})"}
 enum E {D, C=5, B, A};
 enum {EA=3} EnumAnon = EA;
 int enumType(enum E e) {return EnumAnon;}
+
+
+// CHECK: !36 = metadata !{i32 ()* @testReDecl, metadata !"f{si}()"}
+// CHECK: !37 = metadata !{[10 x i32]* @After, metadata !"a(10:si)"}
+// CHECK: !38 = metadata !{[10 x i32]* @Before, metadata !"a(10:si)"}
+extern int After[];
+extern int Before[10];
+int testReDecl() {return After[0] + Before[0];}
+int After[10];
+int Before[];
+
diff --git a/test/CodeGenCXX/PR19955.cpp b/test/CodeGenCXX/PR19955.cpp
new file mode 100644
index 0000000..9e10155
--- /dev/null
+++ b/test/CodeGenCXX/PR19955.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s --check-prefix X64
+
+extern int __declspec(dllimport) var;
+extern void __declspec(dllimport) fun();
+
+extern int *varp;
+int *varp = &var;
+// CHECK-DAG: @"\01?varp@@3PAHA" = global i32* null
+// X64-DAG: @"\01?varp@@3PEAHEA" = global i32* null
+
+extern void (*funp)();
+void (*funp)() = &fun;
+// CHECK-DAG: @"\01?funp@@3P6AXXZA" = global void ()* null
+// X64-DAG: @"\01?funp@@3P6AXXZEA" = global void ()* null
+
+// CHECK-LABEL: @"\01??__Evarp@@YAXXZ"
+// CHECK-DAG: store i32* @"\01?var@@3HA", i32** @"\01?varp@@3PAHA"
+
+// X64-LABEL: @"\01??__Evarp@@YAXXZ"
+// X64-DAG: store i32* @"\01?var@@3HA", i32** @"\01?varp@@3PEAHEA"
+
+// CHECK-LABEL: @"\01??__Efunp@@YAXXZ"()
+// CHECK-DAG: store void ()* @"\01?fun@@YAXXZ", void ()** @"\01?funp@@3P6AXXZA"
+
+// X64-LABEL: @"\01??__Efunp@@YAXXZ"()
+// X64-DAG: store void ()* @"\01?fun@@YAXXZ", void ()** @"\01?funp@@3P6AXXZEA"
diff --git a/test/CodeGenCXX/PR20038.cpp b/test/CodeGenCXX/PR20038.cpp
new file mode 100644
index 0000000..671b8bc
--- /dev/null
+++ b/test/CodeGenCXX/PR20038.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -g -emit-llvm %s -o - | FileCheck %s
+
+struct C {
+  ~C();
+};
+extern bool b;
+// CHECK: call {{.*}}, !dbg [[DTOR_CALL_LOC:![0-9]*]]
+// CHECK: [[FUN4:.*]] = {{.*}}; [ DW_TAG_subprogram ] {{.*}} [def] [fun4]
+// CHECK: [[DTOR_CALL_LOC]] = metadata !{i32 [[@LINE+2]], i32 0, metadata [[FUN4_BLOCK:.*]], null}
+// CHECK: [[FUN4_BLOCK]] = metadata !{{{[^,]*}}, {{[^,]*}}, metadata [[FUN4]],
+void fun4() { b && (C(), 1); }
diff --git a/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp b/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp
index 7543a1c..3b4a309 100644
--- a/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp
+++ b/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp
@@ -1,4 +1,3 @@
-// REQUIRES: arm64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon %s -emit-llvm -o - | FileCheck %s
 
 typedef unsigned char uint8_t;
diff --git a/test/CodeGenCXX/aarch64-neon.cpp b/test/CodeGenCXX/aarch64-neon.cpp
index fc7de1d..d6f6b0e 100644
--- a/test/CodeGenCXX/aarch64-neon.cpp
+++ b/test/CodeGenCXX/aarch64-neon.cpp
@@ -1,8 +1,8 @@
-// REQUIRES: arm64-registered-target
+// REQUIRES: aarch64-registered-target
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
-// Test whether arm_neon.h can be used in .cpp file.
+// Test whether arm_neon.h works as expected in C++.
 
 #include "arm_neon.h"
 
diff --git a/test/CodeGenCXX/attr-used.cpp b/test/CodeGenCXX/attr-used.cpp
index 26c1597..8617346 100644
--- a/test/CodeGenCXX/attr-used.cpp
+++ b/test/CodeGenCXX/attr-used.cpp
@@ -15,3 +15,13 @@
     void __attribute__((used)) f() {}
   };
 };
+
+struct X2 {
+  // We must delay emission of bar() until foo() has had its body parsed,
+  // otherwise foo() would not be emitted.
+  void __attribute__((used)) bar() { foo(); }
+  void foo() { }
+
+  // CHECK: define linkonce_odr {{.*}} @_ZN2X23barEv
+  // CHECK: define linkonce_odr {{.*}} @_ZN2X23fooEv
+};
diff --git a/test/CodeGenCXX/blocks-cxx11.cpp b/test/CodeGenCXX/blocks-cxx11.cpp
index 9ff5826..9df67f7 100644
--- a/test/CodeGenCXX/blocks-cxx11.cpp
+++ b/test/CodeGenCXX/blocks-cxx11.cpp
@@ -106,7 +106,7 @@
   // CHECK:      [[TO_DESTROY:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
   // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[LAMBDA_T]]* [[THIS]], i32 0, i32 0
-  // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* [[T0]], {{.*}}* [[T1]])
+  // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* [[T0]], {{.*}}* nonnull [[T1]])
   // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
   // CHECK-NEXT: call void @_ZN20test_block_in_lambda9takeBlockEU13block_pointerFvvE(void ()* [[T0]])
   // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AD1Ev({{.*}}* [[TO_DESTROY]])
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 8a6fdac..f1d829a 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -164,7 +164,7 @@
 
   // CHECK-NOT:  br
   // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-  // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* [[X]])
+  // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* nonnull [[X]])
   // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]]
   // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
   // CHECK-NEXT: br label
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index 338da57..f318c7c 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -357,7 +357,7 @@
   // CHECK-NEXT: br i1 [[AND]]
 }
 
-// CHECK-LABEL: define void @_Z18downcast_referenceR1B(%class.B* %b)
+// CHECK-LABEL: define void @_Z18downcast_referenceR1B(%class.B* nonnull %b)
 void downcast_reference(B &b) {
   (void) static_cast<C&>(b);
   // Alignment check from EmitTypeCheck(TCK_DowncastReference, ...)
diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp
index c6aaf0f..d7d84a8 100644
--- a/test/CodeGenCXX/class-layout.cpp
+++ b/test/CodeGenCXX/class-layout.cpp
@@ -94,9 +94,9 @@
 
 // Shouldn't crash.
 namespace Test8 {
-	struct A {};

-	struct D { int a; };

-	struct B : virtual D, A { };

-	struct C : B, A { void f() {} };

-	C c;

+  struct A {};
+  struct D { int a; };
+  struct B : virtual D, A { };
+  struct C : B, A { void f() {} };
+  C c;
 }
diff --git a/test/CodeGenCXX/conditional-gnu-ext.cpp b/test/CodeGenCXX/conditional-gnu-ext.cpp
index 44ebf98..dd93467 100644
--- a/test/CodeGenCXX/conditional-gnu-ext.cpp
+++ b/test/CodeGenCXX/conditional-gnu-ext.cpp
@@ -83,7 +83,7 @@
     // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]]
     // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]])
     // CHECK-NEXT: br i1 [[BOOL]]
-    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* [[T0]])
+    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* nonnull [[T0]])
     // CHECK-NEXT: br label
     // CHECK:      call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
     // CHECK-NEXT: br label
@@ -97,7 +97,7 @@
     // CHECK-NEXT: call  void @_ZN5test312test1_helperEv([[B]]* sret [[TEMP]])
     // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]])
     // CHECK-NEXT: br i1 [[BOOL]]
-    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* [[TEMP]])
+    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* nonnull [[TEMP]])
     // CHECK-NEXT: br label
     // CHECK:      call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
     // CHECK-NEXT: br label
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index 1905933..d99b184 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -532,10 +532,10 @@
     // CHECK: call void @_ZN13InitFromConst7consumeIdEEvT_(double 4.300000e+00)
     consume(d);
 
-    // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE)
+    // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* nonnull @_ZN13InitFromConstL1sE)
     consume<const S&>(s);
 
-    // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE)
+    // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* nonnull @_ZN13InitFromConstL1sE)
     consume<const S&>(r);
 
     // CHECK: call void @_ZN13InitFromConst7consumeIPKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE)
diff --git a/test/CodeGenCXX/constructor-direct-call.cpp b/test/CodeGenCXX/constructor-direct-call.cpp
index 7a2a600..0cbf0f4 100644
--- a/test/CodeGenCXX/constructor-direct-call.cpp
+++ b/test/CodeGenCXX/constructor-direct-call.cpp
@@ -54,7 +54,6 @@
   // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
   var.Test3::Test3();
 
-  // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* %var2)
+  // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* nonnull %var2)
   var.Test3::Test3(var2);
 }
-
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
index 477a439..51d1cbc 100644
--- a/test/CodeGenCXX/constructor-init.cpp
+++ b/test/CodeGenCXX/constructor-init.cpp
@@ -163,7 +163,7 @@
 
 // Make sure that the instantiated constructor initializes start and
 // end properly.
-// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* %other) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* nonnull %other) unnamed_addr
 // CHECK: {{store.*null}}
 // CHECK: {{store.*null}}
 // CHECK: ret
diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp
index 02c28c7..b99c5a1 100644
--- a/test/CodeGenCXX/constructors.cpp
+++ b/test/CodeGenCXX/constructors.cpp
@@ -21,10 +21,10 @@
 A::A(struct Undeclared &ref) : mem(0) {}
 
 // Check that delegation works.
-// CHECK-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
 // CHECK: call void @_ZN6MemberC1Ei(
 
-// CHECK-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
 // CHECK: call void @_ZN1AC2ER10Undeclared(
 
 A::A(ValueClass v) : mem(v.y - v.x) {}
@@ -43,11 +43,11 @@
 
 B::B(struct Undeclared &ref) : A(ref), mem(1) {}
 
-// CHECK-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
 // CHECK: call void @_ZN1AC2ER10Undeclared(
 // CHECK: call void @_ZN6MemberC1Ei(
 
-// CHECK-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
 // CHECK: call void @_ZN1BC2ER10Undeclared(
 
 
diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp
index c3be962..78a76bb 100644
--- a/test/CodeGenCXX/convert-to-fptr.cpp
+++ b/test/CodeGenCXX/convert-to-fptr.cpp
@@ -39,4 +39,4 @@
 }
 
 // CHECK: call i32 (i32)* (%struct.A*)* @_ZN1AcvPFiiEEv
-// CHECK: call i32 (i32)* (%struct.B*)* @_ZN1BcvRFiiEEv
+// CHECK: call nonnull i32 (i32)* (%struct.B*)* @_ZN1BcvRFiiEEv
diff --git a/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
index ae21141..3f0833b 100644
--- a/test/CodeGenCXX/copy-assign-synthesis-1.cpp
+++ b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
@@ -1,4 +1,3 @@
-// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
 // RUN: FileCheck %s
 // RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
@@ -93,5 +92,4 @@
   dstY.pr();
 }
 
-// CHECK: define linkonce_odr %struct.X* @_ZN1XaSERKS_
-
+// CHECK: define linkonce_odr nonnull %struct.X* @_ZN1XaSERKS_
diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp
index 727af1b..0f6ee1e 100644
--- a/test/CodeGenCXX/copy-constructor-elim-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -21,7 +21,7 @@
     Derived(const Other &O);
   };
 
-  // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* returned %this, %"struct.no_elide_base::Other"* %O) unnamed_addr
+  // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* returned %this, %"struct.no_elide_base::Other"* nonnull %O) unnamed_addr
   Derived::Derived(const Other &O) 
     // CHECK: call {{.*}} @_ZNK13no_elide_base5OthercvNS_4BaseEEv
     // CHECK: call {{.*}} @_ZN13no_elide_base4BaseC2ERKS0_
@@ -74,4 +74,3 @@
     return a.value;
   }
 }
-
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
index 47c34ca..aeb920d 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -3,5 +3,5 @@
 struct A { virtual void a(); };
 A x(A& y) { return y; }
 
-// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A*) unnamed_addr
+// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A* nonnull) unnamed_addr
 // CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp
index ab36153..bb06bc1 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -21,7 +21,7 @@
 };
 
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X*) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X* nonnull) unnamed_addr
 struct X  : M, N, P { // ...
   X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd),
         au_i1(1234), au1_4("MASKED") {}
@@ -136,7 +136,7 @@
   B b2 = b1;
 }
 
-// CHECK:    define linkonce_odr [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_(
+// CHECK:    define linkonce_odr nonnull [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_(
 // CHECK:      [[THIS:%.*]] = load [[A]]**
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
 // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]**
@@ -158,7 +158,7 @@
 // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false)
 // CHECK-NEXT: ret void
 
-// CHECK-LABEL: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"*) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"* nonnull) unnamed_addr
 // CHECK: call void @_ZN6PR66281TC1Ev
 // CHECK: call void @_ZN6PR66281TC1Ev
 // CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_
diff --git a/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp
index 8779311..d869a2b 100644
--- a/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -119,7 +119,7 @@
 
 namespace test8 {
   // Test that we replace ~zed with ~bar which is an alias to ~foo.
-  // CHECK-DAG: call i32 @__cxa_atexit({{.*}}@_ZN5test83fooD2Ev
+  // CHECK-DAG: call i32 @__cxa_atexit({{.*}}@_ZN5test83barD2Ev
   // CHECK-DAG: @_ZN5test83barD2Ev = alias {{.*}} @_ZN5test83fooD2Ev
   struct foo {
     ~foo();
diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
index 4bc24e8..33bd844 100644
--- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 namespace std {
   typedef decltype(sizeof(int)) size_t;
@@ -431,3 +431,27 @@
     // CHECK: }
   }
 }
+
+namespace DR1070 {
+  struct A {
+    A(std::initializer_list<int>);
+  };
+  struct B {
+    int i;
+    A a;
+  };
+  B b = {1};
+  struct C {
+    std::initializer_list<int> a;
+    B b;
+    std::initializer_list<double> c;
+  };
+  C c = {};
+}
+
+namespace ArrayOfInitList {
+  struct S {
+    S(std::initializer_list<int>);
+  };
+  S x[1] = {};
+}
diff --git a/test/CodeGenCXX/cxx11-initializer-aggregate.cpp b/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
index acc7782..94f3058 100644
--- a/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
+++ b/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
@@ -20,6 +20,25 @@
   // CHECK: %[[INITLIST2:.*]] = alloca %struct.B, align 8
   // CHECK: %[[R:.*]] = getelementptr inbounds %struct.B* %[[INITLIST2:.*]], i32 0, i32 0
   // CHECK: store i32* %{{.*}}, i32** %[[R]], align 8
-  // CHECK: call i32* @_ZN1B1fEv(%struct.B* %[[INITLIST2:.*]])
+  // CHECK: call nonnull i32* @_ZN1B1fEv(%struct.B* %[[INITLIST2:.*]])
   return B{v}.f();
 }
+
+// CHECK: define {{.*}}@__cxx_global_var_init(
+//
+// CHECK: call {{.*}}@_ZN14NonTrivialInit1AC1Ev(
+// CHECK: getelementptr inbounds {{.*}}, i64 1
+// CHECK: br i1
+//
+// CHECK: getelementptr inbounds {{.*}}, i64 1
+// CHECK: icmp eq {{.*}}, i64 30
+// CHECK: br i1
+//
+// CHECK: call i32 @__cxa_atexit(
+namespace NonTrivialInit {
+  struct A { A(); A(const A&) = delete; ~A(); };
+  struct B { A a[20]; };
+  // NB, this must be large enough to be worth memsetting for this test to be
+  // meaningful.
+  B b[30] = {};
+}
diff --git a/test/CodeGenCXX/cxx11-initializer-array-new.cpp b/test/CodeGenCXX/cxx11-initializer-array-new.cpp
index 8de88dc..2393939 100644
--- a/test/CodeGenCXX/cxx11-initializer-array-new.cpp
+++ b/test/CodeGenCXX/cxx11-initializer-array-new.cpp
@@ -28,7 +28,7 @@
 //
 // { 4, 5, 6 }
 //
-// CHECK: %[[S_1:.*]] = getelementptr [3 x %[[S]]]* %[[S_0]], i32 1
+// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i32 1
 //
 // CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
@@ -56,7 +56,6 @@
 // CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]]
 // CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8* %[[ALLOC]], i64 8
 // CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S]]*
-// CHECK: %[[END_AS_S:.*]] = getelementptr inbounds %[[S]]* %[[START_AS_S]], i64 %[[ELTS]]
 //
 // Explicit initializers:
 //
@@ -73,7 +72,7 @@
 //
 // { 4, 5, 6 }
 //
-// CHECK: %[[S_1:.*]] = getelementptr [3 x %[[S]]]* %[[S_0]], i32 1
+// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i32 1
 //
 // CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
@@ -82,26 +81,80 @@
 // CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]]* %[[S_1_1]], i64 1
 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
 //
-// CHECK: %[[S_2:.*]] = getelementptr [3 x %[[S]]]* %[[S_1]], i32 1
+// And the rest.
+//
+// CHECK: %[[S_2:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i32 1
 // CHECK: %[[S_2_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[S_2]] to %[[S]]*
-// CHECK: icmp eq %[[S]]* %[[S_2_AS_S]], %[[END_AS_S]]
+//
+// CHECK: %[[REST:.*]] = sub i64 %[[ELTS]], 6
+// CHECK: icmp eq i64 %[[REST]], 0
 // CHECK: br i1
 //
-// S[n-2][3] initialization loop:
-//
-// CHECK: %[[END_INNER:.*]] = getelementptr inbounds %[[S]]* %{{.*}}, i64 3
+// CHECK: %[[END:.*]] = getelementptr inbounds %[[S]]* %[[S_2_AS_S]], i64 %[[REST]]
 // CHECK: br label
 //
-//   S[3] initialization loop:
-//
-//   CHECK: call void @_ZN1SC1Ev(%[[S]]*
-//   CHECK: %[[NEXT_INNER:.*]] = getelementptr inbounds %[[S]]* %{{.*}}, i64 1
-//   CHECK: icmp eq %[[S]]* %[[NEXT_INNER]], %[[END_INNER]]
-//   CHECK: br i1
-//
-// CHECK: %[[NEXT_OUTER:.*]] = getelementptr [3 x %[[S]]]* %{{.*}}, i32 1
-// CHECK: %[[NEXT_OUTER_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[NEXT_OUTER]] to %[[S]]*
-// CHECK: icmp eq %[[S]]* %[[NEXT_OUTER_AS_S]], %[[END_AS_S]]
+// CHECK: %[[CUR:.*]] = phi %[[S]]* [ %[[S_2_AS_S]], {{.*}} ], [ %[[NEXT:.*]], {{.*}} ]
+// CHECK: call void @_ZN1SC1Ev(%[[S]]* %[[CUR]])
+// CHECK: %[[NEXT]] = getelementptr inbounds %[[S]]* %[[CUR]], i64 1
+// CHECK: icmp eq %[[S]]* %[[NEXT]], %[[END]]
 // CHECK: br i1
 //
 // CHECK: }
+
+struct T { int a; };
+void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
+
+// CHECK-LABEL: define
+//
+// CHECK: load i32* @n
+// CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12)
+// CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3
+//
+// No cookie.
+// CHECK-NOT: @llvm.uadd.with.overflow
+//
+// CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 %{{.*}})
+//
+// CHECK: %[[START_AS_T:.*]] = bitcast i8* %[[ALLOC]] to %[[T:.*]]*
+//
+// Explicit initializers:
+//
+// { 1, 2, 3 }
+//
+// CHECK: %[[T_0:.*]] = bitcast %[[T]]* %[[START_AS_T]] to [3 x %[[T]]]*
+//
+// CHECK: %[[T_0_0:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_0]], i64 0, i64 0
+// CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_0]], i32 0, i32 0
+// CHECK: store i32 1, i32* %[[T_0_0_0]]
+// CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]]* %[[T_0_0]], i64 1
+// CHECK: %[[T_0_1_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_1]], i32 0, i32 0
+// CHECK: store i32 2, i32* %[[T_0_1_0]]
+// CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]]* %[[T_0_1]], i64 1
+// CHECK: %[[T_0_2_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_2]], i32 0, i32 0
+// CHECK: store i32 3, i32* %[[T_0_2_0]]
+//
+// { 4, 5, 6 }
+//
+// CHECK: %[[T_1:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_0]], i32 1
+//
+// CHECK: %[[T_1_0:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_1]], i64 0, i64 0
+// CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_0]], i32 0, i32 0
+// CHECK: store i32 4, i32* %[[T_1_0_0]]
+// CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]]* %[[T_1_0]], i64 1
+// CHECK: %[[T_1_1_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_1]], i32 0, i32 0
+// CHECK: store i32 5, i32* %[[T_1_1_0]]
+// CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]]* %[[T_1_1]], i64 1
+// CHECK: %[[T_1_2_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_2]], i32 0, i32 0
+// CHECK: store i32 6, i32* %[[T_1_2_0]]
+//
+// And the rest gets memset to 0.
+//
+// CHECK: %[[T_2:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_1]], i32 1
+// CHECK: %[[T_2_AS_T:.*]] = bitcast [3 x %[[T]]]* %[[T_2]] to %[[T]]*
+//
+// CHECK: %[[SIZE:.*]] = sub i64 %{{.*}}, 24
+// CHECK: %[[REST:.*]] = bitcast %[[T]]* %[[T_2_AS_T]] to i8*
+// CHECK: call void @llvm.memset.p0i8.i64(i8* %[[REST]], i8 0, i64 %[[SIZE]], i32 4, i1 false)
+//
+// CHECK: }
+
diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp
index 7759d41..9718a93 100644
--- a/test/CodeGenCXX/cxx11-thread-local-reference.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp
@@ -10,10 +10,10 @@
 int &g() { return r; }
 
 // CHECK: define {{.*}} @[[R_INIT:.*]]()
-// CHECK: call i32* @_Z1fv()
+// CHECK: call nonnull i32* @_Z1fv()
 // CHECK: store i32* %{{.*}}, i32** @r, align 8
 
-// CHECK-LABEL: define i32* @_Z1gv()
+// CHECK-LABEL: define nonnull i32* @_Z1gv()
 // CHECK: call i32* @_ZTW1r()
 // CHECK: ret i32* %{{.*}}
 
diff --git a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
index ae49a04..8bdf863 100644
--- a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
+++ b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
@@ -46,7 +46,7 @@
 // CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2)
 // CHECK: call i32 @_ZN1A1fEv({{.*}} @a)
 // CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @a, i32 0, i32 3)
-// CHECK: call void @{{.*}}C1Ev({{.*}} getelementptr inbounds (%struct.A* @a, i32 0, i32 4))
+// CHECK: store double 1.000000e+00, double* getelementptr inbounds ({{.*}} @a, i32 0, i32 4, i32 0)
 
 // No dynamic initialization of 'b':
 
diff --git a/test/CodeGenCXX/debug-info-line-if.cpp b/test/CodeGenCXX/debug-info-line-if.cpp
new file mode 100644
index 0000000..0d4d223
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-line-if.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+// PR19864
+int main() {
+    int v[] = {13, 21, 8, 3, 34, 1, 5, 2};
+    int a = 0, b = 0;
+    for (int x : v)
+      if (x >= 3)
+        ++b;     // CHECK: add nsw{{.*}}, 1
+      else if (x >= 0)
+        ++a;    // CHECK: add nsw{{.*}}, 1
+    // The continuation block if the if statement should not share the
+    // location of the ++a statement. Having it point to the end of
+    // the condition is not ideal either, but it's less missleading.
+
+    // CHECK: br label
+    // CHECK: br label
+    // CHECK: br label {{.*}}, !dbg ![[DBG:.*]]
+    // CHECK: ![[DBG]] = metadata !{i32 [[@LINE-11]], i32 0, metadata !{{.*}}, null}
+
+}
diff --git a/test/CodeGenCXX/debug-info-same-line.cpp b/test/CodeGenCXX/debug-info-same-line.cpp
index c6216b3..965a538 100644
--- a/test/CodeGenCXX/debug-info-same-line.cpp
+++ b/test/CodeGenCXX/debug-info-same-line.cpp
@@ -35,8 +35,8 @@
 
 // Check that we don't give column information (and thus end up with distinct
 // line entries) for two non-inlined calls on the same line.
-// CHECK: call {{.*}}noinline{{.*}}(i32 5, i32 6), !dbg [[NOINLINE:![0-9]*]]
-// CHECK: call {{.*}}noinline{{.*}}(i32 7, i32 8), !dbg [[NOINLINE]]
+// CHECK: call {{.*}}noinline{{.*}}({{i32[ ]?[a-z]*}} 5, {{i32[ ]?[a-z]*}} 6), !dbg [[NOINLINE:![0-9]*]]
+// CHECK: call {{.*}}noinline{{.*}}({{i32[ ]?[a-z]*}} 7, {{i32[ ]?[a-z]*}} 8), !dbg [[NOINLINE]]
 
 // FIXME: These should be separate locations but because the two calls have the
 // same line /and/ column, they get coalesced into a single inlined call by
@@ -50,8 +50,8 @@
 // Even if the functions are marked inline but do not get inlined, they
 // shouldn't use column information, and thus should be at the same debug
 // location.
-// CHECK: call {{.*}}inlsum{{.*}}(i32 13, i32 14), !dbg [[INL_FIRST:![0-9]*]]
-// CHECK: call {{.*}}inlsum{{.*}}(i32 15, i32 16), !dbg [[INL_SECOND:![0-9]*]]
+// CHECK: call {{.*}}inlsum{{.*}}({{i32[ ]?[a-z]*}} 13, {{i32[ ]?[a-z]*}} 14), !dbg [[INL_FIRST:![0-9]*]]
+// CHECK: call {{.*}}inlsum{{.*}}({{i32[ ]?[a-z]*}} 15, {{i32[ ]?[a-z]*}} 16), !dbg [[INL_SECOND:![0-9]*]]
 
 // [[FIRST_INLINE]] =
 // [[SECOND_INLINE]] =
diff --git a/test/CodeGenCXX/decl-ref-init.cpp b/test/CodeGenCXX/decl-ref-init.cpp
index dbbbe97..333e388 100644
--- a/test/CodeGenCXX/decl-ref-init.cpp
+++ b/test/CodeGenCXX/decl-ref-init.cpp
@@ -23,5 +23,5 @@
 	const A& rca2 = d();
 }
 
-// CHECK: call %struct.A* @_ZN1BcvR1AEv
-// CHECK: call %struct.A* @_ZN1BcvR1AEv
+// CHECK: call nonnull %struct.A* @_ZN1BcvR1AEv
+// CHECK: call nonnull %struct.A* @_ZN1BcvR1AEv
diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp
index 4375600..7910942 100644
--- a/test/CodeGenCXX/default-arg-temps.cpp
+++ b/test/CodeGenCXX/default-arg-temps.cpp
@@ -16,12 +16,12 @@
 // CHECK-LABEL: define void @_Z1gv()
 void g() {
   // CHECK:      call void @_ZN1TC1Ev([[T:%.*]]* [[AGG1:%.*]])
-  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG1]])
+  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* nonnull [[AGG1]])
   // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG1]])
   f();
 
   // CHECK-NEXT: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG2:%.*]])
-  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG2]])
+  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* nonnull [[AGG2]])
   // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG2]])
   f();
 
diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp
index 675c50c..7589cf6 100644
--- a/test/CodeGenCXX/derived-to-base-conv.cpp
+++ b/test/CodeGenCXX/derived-to-base-conv.cpp
@@ -33,9 +33,9 @@
   test0_helper(x);
   // CHECK-LABEL:    define void @_Z5test01X(
   // CHECK:      [[TMP:%.*]] = alloca [[A:%.*]], align
-  // CHECK-NEXT: [[T0:%.*]] = call [[B:%.*]]* @_ZN1XcvR1BEv(
+  // CHECK-NEXT: [[T0:%.*]] = call nonnull [[B:%.*]]* @_ZN1XcvR1BEv(
   // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]*
-  // CHECK-NEXT: call void @_ZN1AC1ERKS_([[A]]* [[TMP]], [[A]]* [[T1]])
+  // CHECK-NEXT: call void @_ZN1AC1ERKS_([[A]]* [[TMP]], [[A]]* nonnull [[T1]])
   // CHECK-NEXT: call void @_Z12test0_helper1A([[A]]* [[TMP]])
   // CHECK-NEXT: call void @_ZN1AD1Ev([[A]]* [[TMP]])
   // CHECK-NEXT: ret void
diff --git a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
index b7a5554..cf876b4 100644
--- a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
+++ b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
@@ -9,7 +9,7 @@
   virtual void f();
 };
 
-// CHECK-LABEL: define %struct.B* @_Z1fR1D
+// CHECK-LABEL: define nonnull %struct.B* @_Z1fR1D
 B &f(D &d) {
   // CHECK-NOT: load i8**
   return d;
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index 3d6e603..5c43048 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -4,13 +4,13 @@
 // CHECK-DAG: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
 // CHECK-DAG: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev
 // CHECK-DAG: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
-// CHECK-DAG: @_ZN5test11SD2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// CHECK-DAG: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
 
 // WIN32-DAG: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
 // WIN32-DAG: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
 // WIN32-DAG: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev
 // WIN32-DAG: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
-// WIN32-DAG: @_ZN5test11SD2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// WIN32-DAG: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
 
 
 struct A {
diff --git a/test/CodeGenCXX/dllexport-members.cpp b/test/CodeGenCXX/dllexport-members.cpp
index c4a1d43..353b952 100644
--- a/test/CodeGenCXX/dllexport-members.cpp
+++ b/test/CodeGenCXX/dllexport-members.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple i686-win32     -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
-// RUN: %clang_cc1 -triple x86_64-win32   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
-// RUN: %clang_cc1 -triple i686-mingw32   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
-// RUN: %clang_cc1 -triple x86_64-mingw32 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
 
 // Helper structs to make templates more expressive.
 struct ImplicitInst_Exported {};
@@ -15,17 +15,6 @@
 extern "C" void* malloc(__SIZE_TYPE__ size);
 extern "C" void free(void* p);
 
-// Used to force non-trivial special members.
-struct ForceNonTrivial {
-  ForceNonTrivial();
-  ~ForceNonTrivial();
-  ForceNonTrivial(const ForceNonTrivial&);
-  ForceNonTrivial& operator=(const ForceNonTrivial&);
-  ForceNonTrivial(ForceNonTrivial&&);
-  ForceNonTrivial& operator=(ForceNonTrivial&&);
-};
-
-
 
 //===----------------------------------------------------------------------===//
 // Class members
@@ -51,10 +40,12 @@
   // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this)
   // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this)
   // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this)
+  // M32-DAG: define linkonce_odr       x86_thiscallcc void @"\01?referencedNonExportedInClass@ExportMembers@@QAEXXZ"
   __declspec(dllexport)                void normalDef();
-  __declspec(dllexport)                void normalInclass() {}
+  __declspec(dllexport)                void normalInclass() { referencedNonExportedInClass(); }
   __declspec(dllexport)                void normalInlineDef();
   __declspec(dllexport)         inline void normalInlineDecl();
+                                       void referencedNonExportedInClass() {}
 
   // M32-DAG: define          dllexport x86_thiscallcc void @"\01?virtualDef@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
   // M64-DAG: define          dllexport                void @"\01?virtualDef@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
@@ -119,10 +110,9 @@
 
   // MSC-DAG: @"\01?StaticField@ExportMembers@@2HA"               = dllexport global i32 1, align 4
   // MSC-DAG: @"\01?StaticConstField@ExportMembers@@2HB"          = dllexport constant i32 1, align 4
-  // FIXME: These three should be weak_odr.
-  // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB"            = linkonce_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB"            = weak_odr dllexport constant i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers11StaticFieldE                   = dllexport global i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE              = dllexport constant i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE     = dllexport constant i32 1, align 4
@@ -243,9 +233,9 @@
 
   // MSC-DAG: @"\01?StaticField@Nested@ExportMembers@@2HA"               = dllexport global i32 1, align 4
   // MSC-DAG: @"\01?StaticConstField@Nested@ExportMembers@@2HB"          = dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB"            = linkonce_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB"            = weak_odr dllexport constant i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE                   = dllexport global i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE              = dllexport constant i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE     = dllexport constant i32 1, align 4
@@ -298,32 +288,32 @@
   // G64-DAG: define dllexport                void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this)
   __declspec(dllexport) ~ExportSpecials();
 
-  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@ABU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*)
-  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@AEBU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*)
-  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@ABU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* nonnull)
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@AEBU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* nonnull)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
   __declspec(dllexport) ExportSpecials(const ExportSpecials&);
 
-  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G64-DAG: define dllexport                %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // M32-DAG: define dllexport x86_thiscallcc nonnull %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // M64-DAG: define dllexport                nonnull %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G32-DAG: define dllexport x86_thiscallcc nonnull %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G64-DAG: define dllexport                nonnull %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
   __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&);
 
-  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@$$QAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*)
-  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*)
-  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@$$QAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* nonnull)
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* nonnull)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
   __declspec(dllexport) ExportSpecials(ExportSpecials&&);
 
-  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
-  // G64-DAG: define dllexport                %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // M32-DAG: define dllexport x86_thiscallcc nonnull %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // M64-DAG: define dllexport                nonnull %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G32-DAG: define dllexport x86_thiscallcc nonnull %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
+  // G64-DAG: define dllexport                nonnull %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* nonnull)
   __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&);
 };
 ExportSpecials::ExportSpecials() {}
@@ -354,10 +344,10 @@
   // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsC1ERKS_(
   __declspec(dllexport) inline ExportInlineSpecials(const ExportInlineSpecials&);
 
-  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@ABU0@@Z"(
-  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(
-  // G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
-  // G64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@ABU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                nonnull %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
+  // G64-DAG: define weak_odr dllexport                nonnull %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
   __declspec(dllexport) ExportInlineSpecials& operator=(const ExportInlineSpecials&);
 
   // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE@$$QAU0@@Z"(
@@ -366,10 +356,10 @@
   // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsC1EOS_(
   __declspec(dllexport) ExportInlineSpecials(ExportInlineSpecials&&) {}
 
-  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
-  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(
-  // G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
-  // G64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                nonnull %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
+  // G64-DAG: define weak_odr dllexport                nonnull %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
   __declspec(dllexport) ExportInlineSpecials& operator=(ExportInlineSpecials&&) { return *this; }
 };
 ExportInlineSpecials::ExportInlineSpecials(const ExportInlineSpecials&) {}
@@ -402,32 +392,32 @@
 // G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this)
 ExportDefaultedDefs::~ExportDefaultedDefs() = default;
 
-// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*)
-// M64-DAG: define weak_odr dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*)
-// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G64-DAG: define weak_odr dllexport                void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G64-DAG: define weak_odr dllexport                void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* nonnull)
+// M64-DAG: define weak_odr dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* nonnull)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G64-DAG: define weak_odr dllexport                void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G64-DAG: define weak_odr dllexport                void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
 __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default;
 
-// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// M64-DAG: define weak_odr dllexport                %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G64-DAG: define weak_odr dllexport                %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// M64-DAG: define weak_odr dllexport                nonnull %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G64-DAG: define weak_odr dllexport                nonnull %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
 inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default;
 
-// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*)
-// M64-DAG: define dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*)
-// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* nonnull)
+// M64-DAG: define dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* nonnull)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
 __declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default;
 
-// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// M64-DAG: define dllexport                %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
-// G64-DAG: define dllexport                %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// M32-DAG: define dllexport x86_thiscallcc nonnull %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// M64-DAG: define dllexport                nonnull %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G32-DAG: define dllexport x86_thiscallcc nonnull %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
+// G64-DAG: define dllexport                nonnull %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* nonnull)
 ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
 
 
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index cd44804..197b18e 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -3,6 +3,8 @@
 // RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
 // RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
 
+// RUN: %clang_cc1 -triple i686-pc-win32 -O1 -mconstructor-aliases -std=c++1y -emit-llvm -o - %s | FileCheck %s --check-prefix=MSC --check-prefix=M32
+
 // Helper structs to make templates more expressive.
 struct ImplicitInst_Exported {};
 struct ExplicitDecl_Exported {};
@@ -18,9 +20,13 @@
 #define UNIQ(name) JOIN(name, __LINE__)
 #define USEVAR(var) int UNIQ(use)() { return var; }
 #define USE(func) void UNIQ(use)() { func(); }
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
 #define INSTVAR(var) template int var;
 #define INST(func) template void func();
 
+// The vftable for struct W is comdat largest because we have RTTI.
+// M32-DAG: $"\01??_7W@@6B@" = comdat largest
+
 
 //===----------------------------------------------------------------------===//
 // Globals
@@ -70,6 +76,22 @@
 // GNU-DAG: @ExternalAutoTypeGlobal                      = dllexport global %struct.External zeroinitializer, align 4
 __declspec(dllexport) auto ExternalAutoTypeGlobal = External();
 
+int f();
+// MSC-DAG: @"\01?x@?0??nonInlineStaticLocalsFunc@@YAHXZ@4HA" = internal {{(unnamed_addr )*}}global i32 0
+// MSC-DAG: @"\01?$S1@?0??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0
+int __declspec(dllexport) nonInlineStaticLocalsFunc() {
+  static int x = f();
+  return x++;
+};
+
+// MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0
+// MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0
+// Note: MinGW doesn't seem to export the static local here.
+inline int __declspec(dllexport) inlineStaticLocalsFunc() {
+  static int x = f();
+  return x++;
+}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -447,3 +469,218 @@
 // GNU-DAG: define dllexport void @_Z17precedenceRedecl2v()
 void __declspec(dllexport) precedenceRedecl2();
 void __declspec(dllimport) precedenceRedecl2() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+struct S {
+  void __declspec(dllexport) a() {}
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@S@@QAEXXZ"
+
+  struct T {
+    void __declspec(dllexport) a() {}
+    // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@S@@QAEXXZ"
+  };
+};
+
+
+struct __declspec(dllexport) T {
+  // Copy assignment operator:
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z"
+
+  // Explicitly defaulted copy constructur:
+  T(const T&) = default;
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.T* @"\01??0T@@QAE@ABU0@@Z"
+
+  void a() {}
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
+
+  static int b;
+  // M32-DAG: @"\01?b@T@@2HA" = external dllexport global i32
+
+  static int c;
+  // M32-DAG: @"\01?c@T@@2HA" = dllexport global i32 0, align 4
+};
+
+USEVAR(T::b)
+int T::c;
+
+template <typename T> struct __declspec(dllexport) U { void foo() {} };
+// The U<int> specialization below must cause the following to be emitted:
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
+// M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z"
+struct __declspec(dllexport) V : public U<int> { };
+
+
+struct __declspec(dllexport) W { virtual void foo() {} };
+// Default ctor:
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@XZ"
+// Copy ctor:
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@ABU0@@Z"
+// vftable:
+// M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i8*), i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)], comdat $"\01??_7W@@6B@"
+// M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[W_VTABLE]], i32 0, i32 1)
+// G32-DAG: @_ZTV1W = weak_odr dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
+
+struct __declspec(dllexport) X : public virtual W {};
+// vbtable:
+// M32-DAG: @"\01??_8X@@7B@" = weak_odr dllexport unnamed_addr constant [2 x i32] [i32 0, i32 4]
+
+struct __declspec(dllexport) Y {
+  // Move assignment operator:
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z"
+
+  int x;
+};
+
+struct __declspec(dllexport) Z { virtual ~Z() {} };
+// The scalar deleting dtor does not get exported:
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_GZ@@UAEPAXI@Z"
+
+
+// The user-defined dtor does get exported:
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
+
+namespace DontUseDtorAlias {
+  struct __declspec(dllexport) A { ~A(); };
+  struct __declspec(dllexport) B : A { ~B(); };
+  A::~A() { }
+  B::~B() { }
+  // Emit a real definition of B's constructor; don't alias it to A's.
+  // M32-DAG: define dllexport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
+}
+
+struct __declspec(dllexport) DefaultedCtorsDtors {
+  DefaultedCtorsDtors() = default;
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"\01??0DefaultedCtorsDtors@@QAE@XZ"
+  ~DefaultedCtorsDtors() = default;
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1DefaultedCtorsDtors@@QAE@XZ"
+};
+
+namespace ReferencedInlineMethodInNestedClass {
+  struct __declspec(dllexport) S {
+    void foo() {
+      t->bar();
+    }
+    struct T {
+      void bar() {}
+    };
+    T *t;
+  };
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
+  // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?bar@T@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
+}
+
+// MS ignores DLL attributes on partial specializations.
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
+
+template <typename T> struct ExplicitlySpecializedClassTemplate {};
+template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f() {} };
+USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct ClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func() {} };
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+
+// MS: ClassTemplate<int> gets exported.
+struct __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
+USEMEMFUNC(ClassTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
+
+// ExportedTemplate is explicitly exported.
+struct __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
+
+// ImportedClassTemplate is explicitly imported.
+struct __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+USEMEMFUNC(ImportedClassTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
+
+// Base class already instantiated without dll attribute.
+struct DerivedFromTemplateD : public ClassTemplate<double> {};
+struct __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+USEMEMFUNC(ClassTemplate<double>, func)
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
+
+// MS: Base class already instantiated with different dll attribute.
+struct __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+struct __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+USEMEMFUNC(ClassTemplate<bool>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
+
+// Base class already specialized without dll attribute.
+struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
+
+// Base class already specialized with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
+
+// Base class already instantiated without dll attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
+
+// MS: A dll attribute propagates through multiple levels of instantiation.
+template <typename T> struct TopClass { void func() {} };
+template <typename T> struct MiddleClass : public TopClass<T> { };
+struct __declspec(dllexport) BottomClas : public MiddleClass<int> { };
+USEMEMFUNC(TopClass<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp
index 7fe48a7..8eab9d4 100644
--- a/test/CodeGenCXX/dllimport-members.cpp
+++ b/test/CodeGenCXX/dllimport-members.cpp
@@ -178,9 +178,9 @@
 
   // MSC-DAG: @"\01?StaticField@ImportMembers@@2HA"               = external dllimport global i32
   // MSC-DAG: @"\01?StaticConstField@ImportMembers@@2HB"          = external dllimport constant i32
-  // MSC-DAG-FIXME: @"\01?StaticConstFieldEqualInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
-  // MSC-DAG-FIXME: @"\01?StaticConstFieldBraceInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
-  // MSC-DAG-FIXME: @"\01?ConstexprField@ImportMembers@@2HB"            = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField@ImportMembers@@2HB"            = available_externally dllimport constant i32 1, align 4
   // GNU-DAG: @_ZN13ImportMembers11StaticFieldE                   = external dllimport global i32
   // GNU-DAG: @_ZN13ImportMembers16StaticConstFieldE              = external dllimport constant i32
   // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldEqualInitE     = external dllimport constant i32
@@ -188,11 +188,9 @@
   // GNU-DAG: @_ZN13ImportMembers14ConstexprFieldE                = external dllimport constant i32
   __declspec(dllimport) static         int  StaticField;
   __declspec(dllimport) static  const  int  StaticConstField;
-  #ifndef MSABI // FIXME
   __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
   __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
   __declspec(dllimport) constexpr static int ConstexprField = 1;
-  #endif
 
   template<int Line, typename T> friend void useMemFun();
 };
@@ -230,11 +228,9 @@
 
 USEMV(ImportMembers, StaticField)
 USEMV(ImportMembers, StaticConstField)
-#ifndef MSABI // FIXME
 USEMV(ImportMembers, StaticConstFieldEqualInit)
 USEMV(ImportMembers, StaticConstFieldBraceInit)
 USEMV(ImportMembers, ConstexprField)
-#endif
 
 
 // Import individual members of a nested class.
@@ -355,9 +351,9 @@
 
   // MSC-DAG: @"\01?StaticField@Nested@ImportMembers@@2HA"               = external dllimport global i32
   // MSC-DAG: @"\01?StaticConstField@Nested@ImportMembers@@2HB"          = external dllimport constant i32
-  // MSC-DAG-FIXME: @"\01?StaticConstFieldEqualInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
-  // MSC-DAG-FIXME: @"\01?StaticConstFieldBraceInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
-  // MSC-DAG-FIXME: @"\01?ConstexprField@Nested@ImportMembers@@2HB"            = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField@Nested@ImportMembers@@2HB"            = available_externally dllimport constant i32 1, align 4
   // GNU-DAG: @_ZN13ImportMembers6Nested11StaticFieldE                   = external dllimport global i32
   // GNU-DAG: @_ZN13ImportMembers6Nested16StaticConstFieldE              = external dllimport constant i32
   // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldEqualInitE     = external dllimport constant i32
@@ -365,11 +361,9 @@
   // GNU-DAG: @_ZN13ImportMembers6Nested14ConstexprFieldE                = external dllimport constant i32
   __declspec(dllimport) static         int  StaticField;
   __declspec(dllimport) static  const  int  StaticConstField;
-  #ifndef MSABI // FIXME
   __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
   __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
   __declspec(dllimport) constexpr static int ConstexprField = 1;
-  #endif
 
   template<int Line, typename T> friend void useMemFun();
 };
@@ -407,11 +401,9 @@
 
 USEMV(ImportMembers::Nested, StaticField)
 USEMV(ImportMembers::Nested, StaticConstField)
-#ifndef MSABI // FIXME
 USEMV(ImportMembers::Nested, StaticConstFieldEqualInit)
 USEMV(ImportMembers::Nested, StaticConstFieldBraceInit)
 USEMV(ImportMembers::Nested, ConstexprField)
-#endif
 
 
 // Import special member functions.
@@ -426,30 +418,30 @@
   // M64-DAG: declare dllimport                void @"\01??1ImportSpecials@@QEAA@XZ"(%struct.ImportSpecials*)
   // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
   // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
-  __declspec(dllimport) ~ImportSpecials() {}
+  __declspec(dllimport) ~ImportSpecials();
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@ABU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*)
-  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@AEBU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*)
-  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
-  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@ABU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* nonnull)
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@AEBU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
   __declspec(dllimport) ImportSpecials(const ImportSpecials&);
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*)
-  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*)
-  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
-  // G64-DAG: declare dllimport                %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // M32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
+  // M64-DAG: declare dllimport                nonnull %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
+  // G64-DAG: declare dllimport                nonnull %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
   __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@$$QAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*)
-  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*)
-  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
-  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@$$QAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* nonnull)
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
   __declspec(dllimport) ImportSpecials(ImportSpecials&&);
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*)
-  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*)
-  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
-  // G64-DAG: declare dllimport                %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // M32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
+  // M64-DAG: declare dllimport                nonnull %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
+  // G64-DAG: declare dllimport                nonnull %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials* nonnull)
   __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);
 };
 USESPECIALS(ImportSpecials)
@@ -473,36 +465,36 @@
   // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(
   __declspec(dllimport) ~ImportInlineSpecials() {}
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@ABU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*)
-  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@AEBU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*)
-  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@ABU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* nonnull)
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@AEBU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
   // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@ABU0@@Z"(
   // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(
   __declspec(dllimport) inline ImportInlineSpecials(const ImportInlineSpecials&);
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // G64-DAG: declare dllimport                %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(
-  // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(
+  // M32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // M64-DAG: declare dllimport                nonnull %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // G64-DAG: declare dllimport                nonnull %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(
   __declspec(dllimport) ImportInlineSpecials& operator=(const ImportInlineSpecials&);
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*)
-  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*)
-  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* nonnull)
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
   // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(
-  // GO1-DAG: define available_externally dllimport x86_thiscallcc void  @_ZN20ImportInlineSpecialsC1EOS_(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(
   __declspec(dllimport) ImportInlineSpecials(ImportInlineSpecials&&) {}
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // G64-DAG: declare dllimport                %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
-  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
-  // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(
+  // M32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // M64-DAG: declare dllimport                nonnull %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // G64-DAG: declare dllimport                nonnull %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* nonnull)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(
   __declspec(dllimport) ImportInlineSpecials& operator=(ImportInlineSpecials&&) { return *this; }
 };
 ImportInlineSpecials::ImportInlineSpecials(const ImportInlineSpecials&) {}
@@ -528,36 +520,36 @@
   // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this)
   __declspec(dllimport) ~ImportDefaulted() = default;
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*)
-  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@AEBU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*)
-  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted*)
-  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* nonnull)
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@AEBU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted* nonnull)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* nonnull)
   __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // G64-DAG: declare dllimport                %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
-  // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  // M32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // M64-DAG: declare dllimport                nonnull %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // G64-DAG: declare dllimport                nonnull %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* nonnull)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* nonnull)
   __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*)
-  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*)
-  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted*)
-  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* nonnull)
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted* nonnull)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* nonnull)
   __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;
 
-  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // G64-DAG: declare dllimport                %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
-  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
-  // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  // M32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // M64-DAG: declare dllimport                nonnull %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // G32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // G64-DAG: declare dllimport                nonnull %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* nonnull)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* nonnull)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* nonnull)
   __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;
 
   ForceNonTrivial v; // ensure special members are non-trivial
@@ -589,30 +581,30 @@
 // G64-DAG: declare dllimport                void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*)
 __declspec(dllimport) ImportDefaultedDefs::~ImportDefaultedDefs() = default;
 
-// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs*)
-// M64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs*)
-// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
-// G64-DAG: declare dllimport                void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
+// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs* nonnull)
+// M64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs* nonnull)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* nonnull)
+// G64-DAG: declare dllimport                void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* nonnull)
 inline ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;
 
-// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
-// M64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
-// G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
-// G64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
+// M32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* nonnull)
+// M64-DAG: declare dllimport                nonnull %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* nonnull)
+// G32-DAG: declare dllimport x86_thiscallcc nonnull %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* nonnull)
+// G64-DAG: declare dllimport                nonnull %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* nonnull)
 inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
 
-// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs*)
-// M64-DAG: define                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs*)
-// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
-// G64-DAG: define                void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
-// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
-// G64-DAG: define                void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* nonnull)
+// M64-DAG: define                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* nonnull)
+// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* nonnull)
+// G64-DAG: define                void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* nonnull)
+// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* nonnull)
+// G64-DAG: define                void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* nonnull)
 ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // dllimport ignored
 
-// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
-// M64-DAG: define                %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
-// G32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
-// G64-DAG: define                %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+// M32-DAG: define x86_thiscallcc nonnull %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* nonnull)
+// M64-DAG: define                nonnull %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* nonnull)
+// G32-DAG: define x86_thiscallcc nonnull %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* nonnull)
+// G64-DAG: define                nonnull %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* nonnull)
 ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // dllimport ignored
 
 USESPECIALS(ImportDefaultedDefs)
diff --git a/test/CodeGenCXX/dllimport-rtti.cpp b/test/CodeGenCXX/dllimport-rtti.cpp
new file mode 100644
index 0000000..7ed7dad
--- /dev/null
+++ b/test/CodeGenCXX/dllimport-rtti.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s | FileCheck %s
+
+struct __declspec(dllimport) S {
+  virtual void f();
+} s;
+// CHECK-DAG: @"\01??_7S@@6B@" = available_externally dllimport
+// CHECK-DAG: @"\01??_R0?AUS@@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R1A@?0A@EA@S@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R2S@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R3S@@8" = linkonce_odr
+
+struct U : S {
+} u;
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
index 87f3c88..d15eea2 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -1,9 +1,13 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s
-// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s
-// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G32 %s
-// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G64 %s
-// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
-// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O1 -o - %s         | FileCheck --check-prefix=GO1 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s         | FileCheck --check-prefix=GO1 %s
+
+// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
+// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC2 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU2 %s
 
 // Helper structs to make templates more expressive.
 struct ImplicitInst_Imported {};
@@ -21,8 +25,10 @@
 #define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
 #define USEVAR(var) USEVARTYPE(int, var)
 #define USE(func) void UNIQ(use)() { func(); }
-
-
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+#define USECLASS(class) void UNIQ(USE)() { class x; }
+#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
+#define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
 
 //===----------------------------------------------------------------------===//
 // Globals
@@ -79,6 +85,23 @@
 namespace ns { __declspec(dllimport) int ExternalGlobal; }
 USEVAR(ns::ExternalGlobal)
 
+int f();
+// MO1-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0
+// MO1-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0
+inline int __declspec(dllimport) inlineStaticLocalsFunc() {
+  static int x = f();
+  return x++;
+};
+USE(inlineStaticLocalsFunc);
+
+// The address of a dllimport global cannot be used in constant initialization.
+// M32-DAG: @"\01?arr@?0??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer
+// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer
+int *initializationFunc() {
+  static int *const arr[] = {&ExternGlobalDecl};
+  return arr[0];
+}
+USE(initializationFunc);
 
 
 //===----------------------------------------------------------------------===//
@@ -219,8 +242,8 @@
 __declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
 USE(noinline)
 
-// MSC-NOT: @"\01?alwaysInline@@YAXXZ"()
-// GNU-NOT: @_Z12alwaysInlinev()
+// MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
+// GNU2-NOT: @_Z12alwaysInlinev()
 __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
 USE(alwaysInline)
 
@@ -501,3 +524,248 @@
 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
 USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+struct __declspec(dllimport) T {
+  void a() {}
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
+
+  static int b;
+  // MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32
+
+  T& operator=(T&) = default;
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@AAU0@@Z"
+
+  T& operator=(T&&) = default;
+  // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
+  // MO1-DAG: define linkonce_odr x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
+};
+USEMEMFUNC(T, a)
+USEVAR(T::b)
+USECOPYASSIGN(T)
+USEMOVEASSIGN(T)
+
+template <typename T> struct __declspec(dllimport) U { void foo() {} };
+// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
+struct __declspec(dllimport) V : public U<int> { };
+USEMEMFUNC(V, foo)
+
+struct __declspec(dllimport) W { virtual void foo() {} };
+USECLASS(W)
+// vftable:
+// MO1-DAG: @"\01??_7W@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)]
+// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
+
+struct __declspec(dllimport) KeyFuncClass {
+  constexpr KeyFuncClass() {}
+  virtual void foo();
+};
+constexpr KeyFuncClass keyFuncClassVar;
+// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
+
+struct __declspec(dllimport) X : public virtual W {};
+USECLASS(X)
+// vbtable:
+// MO1-DAG: @"\01??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
+
+struct __declspec(dllimport) Y {
+  int x;
+};
+
+struct __declspec(dllimport) Z { virtual ~Z() {} };
+USECLASS(Z)
+// User-defined dtor:
+// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
+
+namespace DontUseDtorAlias {
+  struct __declspec(dllimport) A { ~A(); };
+  struct __declspec(dllimport) B : A { ~B(); };
+  inline A::~A() { }
+  inline B::~B() { }
+  // Emit a real definition of B's constructor; don't alias it to A's.
+  // MO1-DAG: available_externally dllimport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
+  USECLASS(B)
+}
+
+namespace Vtordisp {
+  // Don't dllimport the vtordisp.
+  // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
+
+  class Base {
+    virtual void f() {}
+  };
+  template <typename T>
+  class __declspec(dllimport) C : virtual public Base {
+  public:
+    C() {}
+    virtual void f() {}
+  };
+  template class C<char>;
+}
+
+namespace ClassTemplateStaticDef {
+  // Regular template static field:
+  template <typename T> struct __declspec(dllimport) S {
+    static int x;
+  };
+  template <typename T> int S<T>::x;
+  // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
+  int f() { return S<int>::x; }
+
+  // Partial class template specialization static field:
+  template <typename A> struct T;
+  template <typename A> struct __declspec(dllimport) T<A*> {
+    static int x;
+  };
+  template <typename A> int T<A*>::x;
+  // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = available_externally dllimport global i32 0
+  int g() { return T<void*>::x; }
+}
+
+namespace PR19933 {
+// Don't dynamically initialize dllimport vars.
+// MSC2-NOT: @llvm.global_ctors
+// GNU2-NOT: @llvm.global_ctors
+
+  struct NonPOD { NonPOD(); };
+  template <typename T> struct A { static NonPOD x; };
+  template <typename T> NonPOD A<T>::x;
+  template struct __declspec(dllimport) A<int>;
+  // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
+
+  int f();
+  template <typename T> struct B { static int x; };
+  template <typename T> int B<T>::x = f();
+  template struct __declspec(dllimport) B<int>;
+  // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
+
+  constexpr int g() { return 42; }
+  template <typename T> struct C { static int x; };
+  template <typename T> int C<T>::x = g();
+  template struct __declspec(dllimport) C<int>;
+  // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
+
+  template <int I> struct D { static int x, y; };
+  template <int I> int D<I>::x = I + 1;
+  template <int I> int D<I>::y = I + f();
+  template struct __declspec(dllimport) D<42>;
+  // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
+  // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
+}
+
+// MS ignores DLL attributes on partial specializations.
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
+
+template <typename T> struct ExplicitlySpecializedClassTemplate {};
+template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f() {} };
+USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct ClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func() {} };
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+
+// MS: ClassTemplate<int> gets imported.
+struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
+USEMEMFUNC(ClassTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
+
+// ImportedTemplate is explicitly imported.
+struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+USEMEMFUNC(ImportedClassTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
+
+// ExportedTemplate is explicitly exported.
+struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+USEMEMFUNC(ExportedClassTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
+
+// Base class already instantiated without attribute.
+struct DerivedFromTemplateD : public ClassTemplate<double> {};
+struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+USEMEMFUNC(ClassTemplate<double>, func)
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
+
+// MS: Base class already instantiated with dfferent attribute.
+struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+USEMEMFUNC(ClassTemplate<bool>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
+
+// Base class already specialized without dll attribute.
+struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
+
+// Base class already specialized with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
+
+// Base class already instantiated without dll attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
+
+// MS: A dll attribute propagates through multiple levels of instantiation.
+template <typename T> struct TopClass { void func() {} };
+template <typename T> struct MiddleClass : public TopClass<T> { };
+struct __declspec(dllimport) BottomClas : public MiddleClass<int> { };
+USEMEMFUNC(TopClass<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index c4ec9dd..c11e90b 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -34,7 +34,7 @@
 // CHECK-NEXT:  [[SELECTORVAR:%.*]] = alloca i32
 // CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
 // CHECK-NEXT:  [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
-// CHECK-NEXT:  invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2)
+// CHECK-NEXT:  invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] nonnull @d2)
 // CHECK-NEXT:     to label %[[CONT:.*]] unwind label %{{.*}}
 //      :     [[CONT]]:   (can't check this in Release-Asserts builds)
 // CHECK:       call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTI7test2_D to i8*), i8* null) [[NR]]
@@ -428,7 +428,7 @@
     // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[EXN]] to [[B:%.*]]*
     // CHECK-NEXT: invoke void @_ZN6test161AC1Ev([[A]]* [[TEMP]])
     // CHECK:      store i1 true, i1* [[TEMP_ACTIVE]]
-    // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* [[T0]], [[A]]* [[TEMP]])
+    // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* [[T0]], [[A]]* nonnull [[TEMP]])
     // CHECK:      store i1 false, i1* [[EXN_ACTIVE]]
     // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXN]],
 
diff --git a/test/CodeGenCXX/empty-nontrivially-copyable.cpp b/test/CodeGenCXX/empty-nontrivially-copyable.cpp
index 9457293..a1098b0 100644
--- a/test/CodeGenCXX/empty-nontrivially-copyable.cpp
+++ b/test/CodeGenCXX/empty-nontrivially-copyable.cpp
@@ -19,7 +19,7 @@
 }
 
 void caller(Empty &e) {
-// CHECK: @_Z6callerR5Empty(%struct.Empty* %e)
+// CHECK: @_Z6callerR5Empty(%struct.Empty* nonnull %e)
 // CHECK: call {{.*}} @_ZN5EmptyC1ERKS_(%struct.Empty* [[NEWTMP:%.*]], %struct.Empty*
 // CHECK: call {{.*}} @_Z3foo5Empty(%struct.Empty* [[NEWTMP]])
   foo(e);
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
index d37e610..ae0c826 100644
--- a/test/CodeGenCXX/exceptions.cpp
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -279,7 +279,7 @@
   // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]])
   // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]*
   // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]])
-  // CHECK:      invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* [[SRC]], [[T_T]]* [[T]])
+  // CHECK:      invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* nonnull [[SRC]], [[T_T]]* nonnull [[T]])
   // CHECK:      invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]])
   // CHECK:      call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]]
   // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]])
diff --git a/test/CodeGenCXX/fastcall.cpp b/test/CodeGenCXX/fastcall.cpp
index 0326ce5..a48dfe1 100644
--- a/test/CodeGenCXX/fastcall.cpp
+++ b/test/CodeGenCXX/fastcall.cpp
@@ -3,7 +3,7 @@
 void __attribute__((fastcall)) foo1(int &y);
 void bar1(int &y) {
   // CHECK-LABEL: define void @_Z4bar1Ri
-  // CHECK: call x86_fastcallcc void @_Z4foo1Ri(i32* inreg %
+  // CHECK: call x86_fastcallcc void @_Z4foo1Ri(i32* inreg nonnull %
   foo1(y);
 }
 
diff --git a/test/CodeGenCXX/goto.cpp b/test/CodeGenCXX/goto.cpp
index 904f95f..36bb2a5 100644
--- a/test/CodeGenCXX/goto.cpp
+++ b/test/CodeGenCXX/goto.cpp
@@ -22,7 +22,7 @@
     // CHECK:      store i1 true, i1* [[CLEANUPACTIVE]]
     // CHECK:      [[NEWCAST:%.*]] = bitcast i8* [[NEW]] to [[V]]*
     // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[TMP]])
-    // CHECK:      invoke void @_ZN5test01VC1ERKNS_1AE([[V]]* [[NEWCAST]], [[A]]* [[TMP]])
+    // CHECK:      invoke void @_ZN5test01VC1ERKNS_1AE([[V]]* [[NEWCAST]], [[A]]* nonnull [[TMP]])
     // CHECK:      store i1 false, i1* [[CLEANUPACTIVE]]
     // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[TMP]])
     A y;
diff --git a/test/CodeGenCXX/implicit-copy-assign-operator.cpp b/test/CodeGenCXX/implicit-copy-assign-operator.cpp
index 2674021..f01d362 100644
--- a/test/CodeGenCXX/implicit-copy-assign-operator.cpp
+++ b/test/CodeGenCXX/implicit-copy-assign-operator.cpp
@@ -40,7 +40,7 @@
   d1 = d2;
 }
 
-// CHECK-LABEL: define linkonce_odr %struct.D* @_ZN1DaSERS_
+// CHECK-LABEL: define linkonce_odr nonnull %struct.D* @_ZN1DaSERS_
 // CHECK: {{call.*_ZN1AaSERS_}}
 // CHECK: {{call.*_ZN1BaSERS_}}
 // CHECK: {{call.*_ZN1CaSERKS_}}
@@ -53,4 +53,3 @@
 // CHECK: call void @_ZN11CopyByValueC1ERKS_
 // CHECK: {{call.*_ZN11CopyByValueaSES_}}
 // CHECK: ret
-
diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp
index bb04318..fa6be99 100644
--- a/test/CodeGenCXX/implicit-copy-constructor.cpp
+++ b/test/CodeGenCXX/implicit-copy-constructor.cpp
@@ -40,7 +40,7 @@
   D d2(d);
 }
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D*) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D* nonnull) unnamed_addr
 // CHECK: call void @_ZN1AC1Ev
 // CHECK: call void @_ZN1CC2ERS_1A
 // CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenCXX/int64_uint64.cpp b/test/CodeGenCXX/int64_uint64.cpp
index ed31dda..aad6ea0 100644
--- a/test/CodeGenCXX/int64_uint64.cpp
+++ b/test/CodeGenCXX/int64_uint64.cpp
@@ -1,9 +1,7 @@
-// REQUIRES: arm-registered-target
 // RUN: %clang_cc1 -triple arm-linux-guneabi \
 // RUN:   -target-cpu cortex-a8 \
 // RUN:   -emit-llvm -w -O1 -o - %s | FileCheck --check-prefix=CHECK-ARM %s
 
-// REQUIRES: arm64-registered-target
 // RUN: %clang_cc1 -triple arm64-linux-gnueabi \
 // RUN:   -target-feature +neon \
 // RUN:   -emit-llvm -w -O1 -o - %s | FileCheck --check-prefix=CHECK-AARCH64 %s
diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp
index 659b437..b926fb2 100644
--- a/test/CodeGenCXX/mangle-lambdas.cpp
+++ b/test/CodeGenCXX/mangle-lambdas.cpp
@@ -192,7 +192,7 @@
   };
   void B::h() { f(); }
 }
-// CHECK-LABEL: define linkonce_odr %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
+// CHECK-LABEL: define linkonce_odr nonnull %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
 
 namespace PR12808 {
   template <typename> struct B {
diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp
index c174e48..373d2b7 100644
--- a/test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -130,3 +130,12 @@
 void A::foo() __restrict && {}
 // CHECK-DAG: @"\01?foo@A@PR19361@@QIHAEXXZ"
 }
+
+int operator"" _deg(long double) { return 0; }
+// CHECK-DAG: @"\01??__K_deg@@YAHO@Z"
+
+template <char...>
+void templ_fun_with_pack() {}
+
+template void templ_fun_with_pack<>();
+// CHECK-DAG: @"\01??$templ_fun_with_pack@$S@@YAXXZ"
diff --git a/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp b/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
index 993199a..e2cbe15 100644
--- a/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
+++ b/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
@@ -1,5 +1,24 @@
 // RUN: %clang_cc1 -Wno-microsoft -fms-extensions -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
+template <typename T, int (T::*)() = nullptr>
+struct J {};
+
+struct __single_inheritance M;
+J<M> m;
+// CHECK-DAG: @"\01?m@@3U?$J@UM@@$0A@@@A"
+
+struct __multiple_inheritance N;
+J<N> n;
+// CHECK-DAG: @"\01?n@@3U?$J@UN@@$HA@@@A"
+
+struct __virtual_inheritance O;
+J<O> o;
+// CHECK-DAG: @"\01?o@@3U?$J@UO@@$IA@A@@@A"
+
+struct P;
+J<P> p;
+// CHECK-DAG: @"\01?p@@3U?$J@UP@@$JA@A@?0@@A"
+
 #pragma pointers_to_members(full_generality, virtual_inheritance)
 
 struct S {
diff --git a/test/CodeGenCXX/mangle-ms-templates.cpp b/test/CodeGenCXX/mangle-ms-templates.cpp
index 24e4f4a..31fda20 100644
--- a/test/CodeGenCXX/mangle-ms-templates.cpp
+++ b/test/CodeGenCXX/mangle-ms-templates.cpp
@@ -262,3 +262,17 @@
   FunctionDefinedWithInjectedName(TypeWithFriendDefinition<int>());
 }
 // CHECK: @"\01?FunctionDefinedWithInjectedName@@YAXU?$TypeWithFriendDefinition@H@@@Z"
+
+// We need to be able to feed GUIDs through a couple rounds of template
+// substitution.
+template <const _GUID *G>
+struct UUIDType3 {
+  void foo() {}
+};
+template <const _GUID *G>
+struct UUIDType4 : UUIDType3<G> {
+  void bar() { UUIDType4::foo(); }
+};
+template struct UUIDType4<&__uuidof(uuid)>;
+// CHECK: "\01?bar@?$UUIDType4@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@QAEXXZ"
+// CHECK: "\01?foo@?$UUIDType3@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@QAEXXZ"
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
index 8fd27b8..998096a 100644
--- a/test/CodeGenCXX/mangle-template.cpp
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -147,7 +147,7 @@
   }
 }
 
-// Report from Jason Merrill on cxx-abi-dev, 2012.01.04.
+// Report from cxx-abi-dev, 2012.01.04.
 namespace test11 {
   int cmp(char a, char b);
   template <typename T, int (*cmp)(T, T)> struct A {};
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index c55e3e0..66cc026 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -280,13 +280,13 @@
   void *v;
 };
 
-// CHECK-LABEL: define %struct.Ops* @_ZN3OpsplERKS_
+// CHECK-LABEL: define nonnull %struct.Ops* @_ZN3OpsplERKS_
 Ops& Ops::operator+(const Ops&) { return *this; }
-// CHECK-LABEL: define %struct.Ops* @_ZN3OpsmiERKS_
+// CHECK-LABEL: define nonnull %struct.Ops* @_ZN3OpsmiERKS_
 Ops& Ops::operator-(const Ops&) { return *this; }
-// CHECK-LABEL: define %struct.Ops* @_ZN3OpsanERKS_
+// CHECK-LABEL: define nonnull %struct.Ops* @_ZN3OpsanERKS_
 Ops& Ops::operator&(const Ops&) { return *this; }
-// CHECK-LABEL: define %struct.Ops* @_ZN3OpsmlERKS_
+// CHECK-LABEL: define nonnull %struct.Ops* @_ZN3OpsmlERKS_
 Ops& Ops::operator*(const Ops&) { return *this; }
 
 // PR5861
@@ -899,7 +899,7 @@
 }
 
 namespace test40 {
-  // CHECK: i32* @_ZZN6test401fEvE1a_0
+  // CHECK: i32* {{.*}} @_ZZN6test401fEvE1a_0
   void h(int&);
   inline void f() {
     if (0) {
diff --git a/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp b/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
index 3361921..6a0a860 100644
--- a/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
+++ b/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i686-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck %s
+// RUN: %clang_cc1 -Wno-non-pod-varargs -emit-llvm %s -o - -triple=i686-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck %s
 
 #include <stdarg.h>
 
@@ -19,9 +19,34 @@
   return sum;
 }
 
+// CHECK-LABEL: define i32 @"\01?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca, ...)
+
 int main() {
   return foo(A(3), 1, 2, 3);
 }
 // CHECK-LABEL: define i32 @main()
-// CHECK: %[[argmem_cast:[^ ]*]] = bitcast <{ %struct.A, i32, i32, i32 }>* %argmem to <{ %struct.A }>*
-// CHECK: call i32 (<{ %struct.A }>*, ...)* @"\01?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca %[[argmem_cast]])
+// CHECK: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.A, i32, i32, i32 }>
+// CHECK: call i32 {{.*bitcast.*}}@"\01?foo@@YAHUA@@ZZ"{{.*}}(<{ %struct.A, i32, i32, i32 }>* inalloca %[[argmem]])
+
+void varargs_zero(...);
+void varargs_one(int, ...);
+void varargs_two(int, int, ...);
+void varargs_three(int, int, int, ...);
+void call_var_args() {
+  A x(3);
+  varargs_zero(x);
+  varargs_one(1, x);
+  varargs_two(1, 2, x);
+  varargs_three(1, 2, 3, x);
+}
+
+// CHECK-LABEL: define void @"\01?call_var_args@@YAXXZ"()
+// CHECK: call void {{.*bitcast.*varargs_zero.*}}(<{ %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_one.*}}(<{ i32, %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_two.*}}(<{ i32, i32, %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_three.*}}(<{ i32, i32, i32, %struct.A }>* inalloca %{{.*}})
+
+// CHECK-LABEL: declare void @"\01?varargs_zero@@YAXZZ"(...)
+// CHECK-LABEL: declare void @"\01?varargs_one@@YAXHZZ"(i32, ...)
+// CHECK-LABEL: declare void @"\01?varargs_two@@YAXHHZZ"(i32, i32, ...)
+// CHECK-LABEL: declare void @"\01?varargs_three@@YAXHHHZZ"(i32, i32, i32, ...)
diff --git a/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp b/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
index 2f8a66e..da58c46 100644
--- a/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
+++ b/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
@@ -33,3 +33,12 @@
 // CHECK: call void {{.*}} @"\01?variadic_sret@C@@QAA?AUS@@PBDZZ"
 // CHECK: call void @"\01?cdecl_sret@C@@QAA?AUS@@XZ"
 // CHECK: call void @"\01?byval_and_sret@C@@QAA?AUS@@U2@@Z"
+
+// __fastcall has similar issues.
+struct A {
+  S __fastcall f(int x);
+};
+S A::f(int x) {
+  return S();
+}
+// CHECK-LABEL: define x86_fastcallcc void @"\01?f@A@@QAI?AUS@@H@Z"(%struct.A* inreg %this, %struct.S* inreg noalias sret %agg.result, i32 %x)
diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
new file mode 100644
index 0000000..225407b
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -0,0 +1,130 @@
+// RUN: %clang_cc1 -emit-llvm -O1 -o - -triple=i386-pc-win32 %s | FileCheck %s
+
+struct S { char a; };
+struct V { virtual void f(); };
+struct A : virtual V {};
+struct B : S, virtual V {};
+struct T {};
+
+T* test0() { return dynamic_cast<T*>((B*)0); }
+// CHECK-LABEL: define noalias %struct.T* @"\01?test0@@YAPAUT@@XZ"()
+// CHECK:   ret %struct.T* null
+
+T* test1(V* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define %struct.T* @"\01?test1@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
+// CHECK:        [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test2(A* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define %struct.T* @"\01?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
+// CHECK:        [[CAST:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST]], align 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[VBOFFS]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test3(B* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define %struct.T* @"\01?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
+// CHECK:        [[VOIDP:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 4
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR:%.*]] to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST]], align 4
+// CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[DELTA]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test4(V* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define %struct.T* @"\01?test4@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
+// CHECK:        [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test5(A* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define %struct.T* @"\01?test5@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
+// CHECK:        [[CHECK:%.*]] = icmp eq %struct.A* %x, null
+// CHECK-NEXT:   br i1 [[CHECK]]
+// CHECK:        [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[VBOFFS]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT:   [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   br label
+// CHECK:        [[RET:%.*]] = phi %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test6(B* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define %struct.T* @"\01?test6@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
+// CHECK:        [[CHECK:%.*]] = icmp eq %struct.B* %x, null
+// CHECK-NEXT:   br i1 [[CHECK]]
+// CHECK:        [[CAST:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[CAST]], i32 4
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR]] to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[DELTA]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT:   [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   br label
+// CHECK:        [[RET:%.*]] = phi %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+void* test7(V* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define i8* @"\01?test7@@YAPAXPAUV@@@Z"(%struct.V* %x)
+// CHECK:        [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT:   [[RET:%.*]] = tail call i8* @__RTCastToVoid(i8* [[CAST]])
+// CHECK-NEXT:   ret i8* [[RET]]
+
+void* test8(A* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define i8* @"\01?test8@@YAPAXPAUA@@@Z"(%struct.A* %x)
+// CHECK:        [[CHECK:%.*]] = icmp eq %struct.A* %x, null
+// CHECK-NEXT:   br i1 [[CHECK]]
+// CHECK:        [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[VBOFFS]]
+// CHECK-NEXT:   [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT:   br label
+// CHECK:        [[RET:%.*]] = phi i8*
+// CHECK-NEXT:   ret i8* [[RET]]
+
+void* test9(B* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define i8* @"\01?test9@@YAPAXPAUB@@@Z"(%struct.B* %x)
+// CHECK:        [[CHECK:%.*]] = icmp eq %struct.B* %x, null
+// CHECK-NEXT:   br i1 [[CHECK]]
+// CHECK:        [[CAST:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[CAST]], i32 4
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR]] to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[DELTA]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT:   br label
+// CHECK:        [[RET:%.*]] = phi i8*
+// CHECK-NEXT:   ret i8* [[RET]]
+
diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
index 4ce8a02..18e8c82 100644
--- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s -check-prefix=X64
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
 // FIXME: Test x86_64 member pointers when codegen no longer asserts on records
 // with virtual bases.
 
@@ -607,6 +607,40 @@
 
 }
 
+namespace pr20007 {
+struct A {
+  void f();
+  void f(int);
+};
+struct B : public A {};
+void test() { void (B::*a)() = &B::f; }
+// CHECK-LABEL: define void @"\01?test@pr20007@@YAXXZ"
+// CHECK: store i8* bitcast (void (%"struct.pr20007::A"*)* @"\01?f@A@pr20007@@QAEXXZ" to i8*)
+}
+
+namespace pr20007_kw {
+struct A {
+  void f();
+  void f(int);
+};
+struct __single_inheritance B;
+struct B : public A {};
+void test() { void (B::*a)() = &B::f; }
+// CHECK-LABEL: define void @"\01?test@pr20007_kw@@YAXXZ"
+// CHECK: store i8* bitcast (void (%"struct.pr20007_kw::A"*)* @"\01?f@A@pr20007_kw@@QAEXXZ" to i8*)
+}
+
+namespace pr19987 {
+template <typename T>
+struct S {
+  int T::*x;
+};
+
+struct U : S<U> {};
+
+static_assert(sizeof(S<U>::x) == 12, "");
+}
+
 #else
 struct __virtual_inheritance A;
 #ifdef MEMFUN
diff --git a/test/CodeGenCXX/microsoft-abi-rtti.cpp b/test/CodeGenCXX/microsoft-abi-rtti.cpp
index 4b91466..062f597 100644
--- a/test/CodeGenCXX/microsoft-abi-rtti.cpp
+++ b/test/CodeGenCXX/microsoft-abi-rtti.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 2>/dev/null %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 2>/dev/null %s | FileCheck --check-prefix=X64 %s
 
 struct N {};
 struct M : private N {};
@@ -25,122 +26,242 @@
 struct A2 : Z2, Y2 {};
 struct B2 : virtual A2 { B2() {} virtual void f() {} } b2;
 
-// CHECK: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUB2@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3B2@@8" }
-// CHECK: @"\01??_R0?AUB2@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }
-// CHECK: @"\01??_R3B2@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 3, i32 4, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([5 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2B2@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2B2@@8" = linkonce_odr constant [5 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8", %MSRTTIBaseClassDescriptor* @"\01??_R13A@3EA@Y2@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUB2@@@8" to i8*), i32 3, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3B2@@8" }
-// CHECK: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 0, i32 4, i32 80, %MSRTTIClassHierarchyDescriptor* @"\01??_R3A2@@8" }
-// CHECK: @"\01??_R0?AUA2@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }
-// CHECK: @"\01??_R3A2@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 1, i32 3, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([4 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2A2@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2A2@@8" = linkonce_odr constant [4 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %MSRTTIBaseClassDescriptor* @"\01??_R13?0A@EA@Y2@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3A2@@8" }
-// CHECK: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
-// CHECK: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }
-// CHECK: @"\01??_R3Z2@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 1, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([2 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2Z2@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R13?0A@EA@Y2@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
-// CHECK: @"\01??_R0?AUY2@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }
-// CHECK: @"\01??_R3Y2@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 1, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([2 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2Y2@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
-// CHECK: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
-// CHECK: @"\01??_R13A@3EA@Y2@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 0, i32 4, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
-// CHECK: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 12, i32 8, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUB2@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3B2@@8" }
-// CHECK: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUA2@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3A2@@8" }
-// CHECK: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUA2@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3A2@@8" }
-// CHECK: @"\01??_R4Y2@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUY2@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
-// CHECK: @"\01??_R4Z2@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUZ2@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
-// CHECK: @"\01??_R4B1@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUB1@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3B1@@8" }
-// CHECK: @"\01??_R0?AUB1@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }
-// CHECK: @"\01??_R3B1@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 2, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([3 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2B1@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2B1@@8" = linkonce_odr constant [3 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUB1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3B1@@8" }
-// CHECK: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 80, %MSRTTIClassHierarchyDescriptor* @"\01??_R3A1@@8" }
-// CHECK: @"\01??_R0?AUA1@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }
-// CHECK: @"\01??_R3A1@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 1, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([2 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2A1@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2A1@@8" = linkonce_odr constant [2 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3A1@@8" }
-// CHECK: @"\01??_R4A1@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUA1@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3A1@@8" }
-// CHECK: @"\01??_R4Y1@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUY1@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y1@@8" }
-// CHECK: @"\01??_R0?AUY1@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }
-// CHECK: @"\01??_R3Y1@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 3, i32 6, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([7 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2Y1@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUY1@@@8" to i8*), i32 5, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y1@@8" }
-// CHECK: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUW1@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3W1@@8" }
-// CHECK: @"\01??_R0?AUW1@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }
-// CHECK: @"\01??_R3W1@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 3, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([4 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2W1@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2W1@@8" = linkonce_odr constant [4 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 80, %MSRTTIClassHierarchyDescriptor* @"\01??_R3V1@@8" }
-// CHECK: @"\01??_R0?AUV1@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }
-// CHECK: @"\01??_R3V1@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 2, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([3 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2V1@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2V1@@8" = linkonce_odr constant [3 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3V1@@8" }
-// CHECK: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3X1@@8" }
-// CHECK: @"\01??_R0?AUX1@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\08" { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }
-// CHECK: @"\01??_R3X1@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 1, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([2 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2X1@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2X1@@8" = linkonce_odr constant [2 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3X1@@8" }
-// CHECK: @"\01??_R4W1@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUW1@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3W1@@8" }
-// CHECK: @"\01??_R4V1@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUV1@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3V1@@8" }
-// CHECK: @"\01??_R4X1@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\08"* @"\01??_R0?AUX1@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3X1@@8" }
-// CHECK: @"\01??_R4C@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUC@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3C@@8" }
-// CHECK: @"\01??_R0?AUC@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }
-// CHECK: @"\01??_R3C@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 3, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([4 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2C@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2C@@8" = linkonce_odr constant [4 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8", %MSRTTIBaseClassDescriptor* @"\01??_R13?0A@EA@B@@8", %MSRTTIBaseClassDescriptor* @"\01??_R13?0A@EA@A@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUC@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3C@@8" }
-// CHECK: @"\01??_R13?0A@EA@B@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3B@@8" }
-// CHECK: @"\01??_R0?AUB@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }
-// CHECK: @"\01??_R3B@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 2, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([3 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2B@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2B@@8" = linkonce_odr constant [3 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3B@@8" }
-// CHECK: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3A@@8" }
-// CHECK: @"\01??_R0?AUA@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }
-// CHECK: @"\01??_R3A@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 1, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([2 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2A@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2A@@8" = linkonce_odr constant [2 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R13?0A@EA@A@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3A@@8" }
-// CHECK: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVY@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y@@8" }
-// CHECK: @"\01??_R0?AVY@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }
-// CHECK: @"\01??_R3Y@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 3, i32 9, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([10 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2Y@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2Y@@8" = linkonce_odr constant [10 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8", %MSRTTIBaseClassDescriptor* @"\01??_R13?0A@EN@W@@8", %MSRTTIBaseClassDescriptor* @"\01??_R17?0A@EN@M@@8", %MSRTTIBaseClassDescriptor* @"\01??_R17?0A@EN@N@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVY@@@8" to i8*), i32 8, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y@@8" }
-// CHECK: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Z@@8" }
-// CHECK: @"\01??_R0?AVZ@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }
-// CHECK: @"\01??_R3Z@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 1, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([2 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2Z@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2Z@@8" = linkonce_odr constant [2 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3Z@@8" }
-// CHECK: @"\01??_R13?0A@EN@W@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 4, i32 -1, i32 0, i32 77, %MSRTTIClassHierarchyDescriptor* @"\01??_R3W@@8" }
-// CHECK: @"\01??_R0?AVW@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }
-// CHECK: @"\01??_R3W@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 3, i32 5, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([6 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2W@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2W@@8" = linkonce_odr constant [6 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8", %MSRTTIBaseClassDescriptor* @"\01??_R13?0A@EN@M@@8", %MSRTTIBaseClassDescriptor* @"\01??_R13?0A@EN@N@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3W@@8" }
-// CHECK: @"\01??_R13?0A@EN@M@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 77, %MSRTTIClassHierarchyDescriptor* @"\01??_R3M@@8" }
-// CHECK: @"\01??_R0?AUM@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }
-// CHECK: @"\01??_R3M@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 2, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([3 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2M@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2M@@8" = linkonce_odr constant [3 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3M@@8" }
-// CHECK: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %MSRTTIClassHierarchyDescriptor* @"\01??_R3N@@8" }
-// CHECK: @"\01??_R0?AUN@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }
-// CHECK: @"\01??_R3N@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 1, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([2 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2N@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2N@@8" = linkonce_odr constant [2 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3N@@8" }
-// CHECK: @"\01??_R13?0A@EN@N@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 77, %MSRTTIClassHierarchyDescriptor* @"\01??_R3N@@8" }
-// CHECK: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 93, %MSRTTIClassHierarchyDescriptor* @"\01??_R3V@@8" }
-// CHECK: @"\01??_R0?AVV@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }
-// CHECK: @"\01??_R3V@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 2, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([3 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2V@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2V@@8" = linkonce_odr constant [3 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8", %MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3V@@8" }
-// CHECK: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %MSRTTIClassHierarchyDescriptor* @"\01??_R3X@@8" }
-// CHECK: @"\01??_R0?AUX@@@8" = linkonce_odr global %"MSRTTITypeDescriptor\07" { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }
-// CHECK: @"\01??_R3X@@8" = linkonce_odr constant %MSRTTIClassHierarchyDescriptor { i32 0, i32 0, i32 1, %MSRTTIBaseClassDescriptor** getelementptr inbounds ([2 x %MSRTTIBaseClassDescriptor*]* @"\01??_R2X@@8", i32 0, i32 0) }
-// CHECK: @"\01??_R2X@@8" = linkonce_odr constant [2 x %MSRTTIBaseClassDescriptor*] [%MSRTTIBaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %MSRTTIBaseClassDescriptor* null]
-// CHECK: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 73, %MSRTTIClassHierarchyDescriptor* @"\01??_R3X@@8" }
-// CHECK: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 8, i32 -1, i32 0, i32 77, %MSRTTIClassHierarchyDescriptor* @"\01??_R3M@@8" }
-// CHECK: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 8, i32 -1, i32 0, i32 77, %MSRTTIClassHierarchyDescriptor* @"\01??_R3N@@8" }
-// CHECK: @"\01??_R1A@33FN@V@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 4, i32 4, i32 93, %MSRTTIClassHierarchyDescriptor* @"\01??_R3V@@8" }
-// CHECK: @"\01??_R1A@33EJ@X@@8" = linkonce_odr constant %MSRTTIBaseClassDescriptor { i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 4, i32 4, i32 73, %MSRTTIClassHierarchyDescriptor* @"\01??_R3X@@8" }
-// CHECK: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 8, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVY@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3Y@@8" }
-// CHECK: @"\01??_R4W@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVW@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3W@@8" }
-// CHECK: @"\01??_R4Z@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVZ@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3Z@@8" }
-// CHECK: @"\01??_R4V@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AVV@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3V@@8" }
-// CHECK: @"\01??_R4X@@6B@" = linkonce_odr constant %MSRTTICompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%"MSRTTITypeDescriptor\07"* @"\01??_R0?AUX@@@8" to i8*), %MSRTTIClassHierarchyDescriptor* @"\01??_R3X@@8" }
+// CHECK: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }
+// CHECK: @"\01??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }
+// CHECK: @"\01??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, %rtti.BaseClassDescriptor** getelementptr inbounds ([5 x %rtti.BaseClassDescriptor*]* @"\01??_R2B2@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2B2@@8" = linkonce_odr constant [5 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8", %rtti.BaseClassDescriptor* @"\01??_R13A@3EA@Y2@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), i32 3, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }
+// CHECK: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }
+// CHECK: @"\01??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }
+// CHECK: @"\01??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2A2@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2A2@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
+// CHECK: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }
+// CHECK: @"\01??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Z2@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R13?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
+// CHECK: @"\01??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }
+// CHECK: @"\01??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y2@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
+// CHECK: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
+// CHECK: @"\01??_R13A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
+// CHECK: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 12, i32 8, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }
+// CHECK: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }
+// CHECK: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }
+// CHECK: @"\01??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
+// CHECK: @"\01??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
+// CHECK: @"\01??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" }
+// CHECK: @"\01??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }
+// CHECK: @"\01??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2B1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2B1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" }
+// CHECK: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }
+// CHECK: @"\01??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }
+// CHECK: @"\01??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2A1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2A1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }
+// CHECK: @"\01??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }
+// CHECK: @"\01??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" }
+// CHECK: @"\01??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }
+// CHECK: @"\01??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, %rtti.BaseClassDescriptor** getelementptr inbounds ([7 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i8*), i32 5, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" }
+// CHECK: @"\01??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }
+// CHECK: @"\01??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2W1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2W1@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }
+// CHECK: @"\01??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }
+// CHECK: @"\01??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2V1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2V1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }
+// CHECK: @"\01??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }
+// CHECK: @"\01??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2X1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2X1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }
+// CHECK: @"\01??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" }
+// CHECK: @"\01??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }
+// CHECK: @"\01??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }
+// CHECK: @"\01??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" }
+// CHECK: @"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }
+// CHECK: @"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2C@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2C@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@A@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" }
+// CHECK: @"\01??_R13?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" }
+// CHECK: @"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }
+// CHECK: @"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2B@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2B@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" }
+// CHECK: @"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }
+// CHECK: @"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2A@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2A@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R13?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" }
+// CHECK: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }
+// CHECK: @"\01??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }
+// CHECK: @"\01??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, %rtti.BaseClassDescriptor** getelementptr inbounds ([10 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Y@@8" = linkonce_odr constant [10 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@W@@8", %rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), i32 8, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }
+// CHECK: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }
+// CHECK: @"\01??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }
+// CHECK: @"\01??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Z@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Z@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }
+// CHECK: @"\01??_R13?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }
+// CHECK: @"\01??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }
+// CHECK: @"\01??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, %rtti.BaseClassDescriptor** getelementptr inbounds ([6 x %rtti.BaseClassDescriptor*]* @"\01??_R2W@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2W@@8" = linkonce_odr constant [6 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }
+// CHECK: @"\01??_R13?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }
+// CHECK: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }
+// CHECK: @"\01??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2M@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2M@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }
+// CHECK: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }
+// CHECK: @"\01??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }
+// CHECK: @"\01??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2N@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2N@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }
+// CHECK: @"\01??_R13?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }
+// CHECK: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }
+// CHECK: @"\01??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }
+// CHECK: @"\01??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2V@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2V@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }
+// CHECK: @"\01??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }
+// CHECK: @"\01??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2X@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2X@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }
+// CHECK: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }
+// CHECK: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }
+// CHECK: @"\01??_R1A@33FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 4, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }
+// CHECK: @"\01??_R1A@33EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 4, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }
+// CHECK: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }
+// CHECK: @"\01??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }
+// CHECK: @"\01??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }
+// CHECK: @"\01??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }
+// CHECK: @"\01??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }
+
+// X64: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }
+// X64: @"\01??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([5 x i32]* @"\01??_R2B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2B2@@8" = linkonce_odr constant [5 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17A@3EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 3, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }
+// X64: @"\01??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2A2@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }
+// X64: @"\01??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R17?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }
+// X64: @"\01??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 24, i32 12, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Z2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }
+// X64: @"\01??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2B1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }
+// X64: @"\01??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2A1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }
+// X64: @"\01??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([7 x i32]* @"\01??_R2Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 5, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }
+// X64: @"\01??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2W1@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }
+// X64: @"\01??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2V1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }
+// X64: @"\01??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2X1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4W1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4V1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4X1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }
+// X64: @"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2C@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }
+// X64: @"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2B@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }
+// X64: @"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2A@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R17?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y@@6BZ@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }
+// X64: @"\01??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([10 x i32]* @"\01??_R2Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Y@@8" = linkonce_odr constant [10 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1BA@?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1BA@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 8, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }
+// X64: @"\01??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Z@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }
+// X64: @"\01??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([6 x i32]* @"\01??_R2W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2W@@8" = linkonce_odr constant [6 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }
+// X64: @"\01??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2M@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }
+// X64: @"\01??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2N@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }
+// X64: @"\01??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2V@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }
+// X64: @"\01??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2X@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1BA@?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1BA@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@73FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 8, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@73EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 8, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y@@6BW@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Z@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4V@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4X@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index 4ff36c0..de1b7aa 100644
--- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -137,10 +137,10 @@
 
 // Test that references aren't destroyed in the callee.
 void ref_small_arg_with_dtor(const SmallWithDtor &s) { }
-// WIN32: define void @"\01?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"(%struct.SmallWithDtor* %s) {{.*}} {
+// WIN32: define void @"\01?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"(%struct.SmallWithDtor* nonnull %s) {{.*}} {
 // WIN32-NOT:   call x86_thiscallcc void @"\01??1SmallWithDtor@@QAE@XZ"
 // WIN32: }
-// WIN64-LABEL: define void @"\01?ref_small_arg_with_dtor@@YAXAEBUSmallWithDtor@@@Z"(%struct.SmallWithDtor* %s)
+// WIN64-LABEL: define void @"\01?ref_small_arg_with_dtor@@YAXAEBUSmallWithDtor@@@Z"(%struct.SmallWithDtor* nonnull %s)
 
 void big_arg_with_dtor(BigWithDtor s) {}
 // WIN64-LABEL: define void @"\01?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(%struct.BigWithDtor* %s)
diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
index 782b9dc..a3127c7 100644
--- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
@@ -119,7 +119,7 @@
   return s;
 }
 
-// CHECK-LABEL: define linkonce_odr %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"()
+// CHECK-LABEL: define linkonce_odr nonnull %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"()
 // CHECK: and i32 {{.*}}, 2
 // CHECK: or i32 {{.*}}, 2
 // CHECK: ret
@@ -129,7 +129,7 @@
   return TheS;
 }
 
-// CHECK-LABEL: define linkonce_odr %struct.S* @"\01?getS@@YAAAUS@@XZ"
+// CHECK-LABEL: define linkonce_odr nonnull %struct.S* @"\01?getS@@YAAAUS@@XZ"
 // CHECK: load i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
 // CHECK: and i32 {{.*}}, 1
 // CHECK: icmp ne i32 {{.*}}, 0
@@ -143,10 +143,78 @@
 //   init.end:
 // CHECK: ret %struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A"
 
+inline int enum_in_function() {
+  // CHECK-LABEL: define linkonce_odr i32 @"\01?enum_in_function@@YAHXZ"()
+  static enum e { foo, bar, baz } x;
+  // CHECK: @"\01?x@?1??enum_in_function@@YAHXZ@4W4e@?1??1@YAHXZ@A"
+  static int y;
+  // CHECK: @"\01?y@?1??enum_in_function@@YAHXZ@4HA"
+  return x + y;
+};
+
+struct T {
+  enum e { foo, bar, baz };
+  int enum_in_struct() {
+    // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @"\01?enum_in_struct@T@@QAEHXZ"
+    static int x;
+    // CHECK: @"\01?x@?1??enum_in_struct@T@@QAEHXZ@4HA"
+    return x++;
+  }
+};
+
+inline int switch_test(int x) {
+  // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test@@YAHH@Z"(i32 %x)
+  switch (x) {
+    static int a;
+    // CHECK: @"\01?a@?3??switch_test@@YAHH@Z@4HA"
+    case 0:
+      a++;
+      return 1;
+    case 1:
+      static int b;
+      // CHECK: @"\01?b@?3??switch_test@@YAHH@Z@4HA"
+      return b++;
+    case 2: {
+      static int c;
+      // CHECK: @"\01?c@?4??switch_test@@YAHH@Z@4HA"
+      return b + c++;
+    }
+  };
+}
+
+int f();
+inline void switch_test2() {
+  // CHECK-LABEL: define linkonce_odr void @"\01?switch_test2@@YAXXZ"()
+  // CHECK: @"\01?x@?2??switch_test2@@YAXXZ@4HA"
+  switch (1) default: static int x = f();
+}
+
+namespace DynamicDLLImportInitVSMangling {
+  // Failing to pop the ExprEvalContexts when instantiating a dllimport var with
+  // dynamic initializer would cause subsequent static local numberings to be
+  // incorrect.
+  struct NonPOD { NonPOD(); };
+  template <typename T> struct A { static NonPOD x; };
+  template <typename T> NonPOD A<T>::x;
+  template struct __declspec(dllimport) A<int>;
+
+  inline int switch_test3() {
+    // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ"
+    static int local;
+    // CHECK: @"\01?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA"
+    return local++;
+  }
+}
+
 void force_usage() {
   UnreachableStatic();
   getS();
   (void)B<int>::foo;  // (void) - force usage
+  enum_in_function();
+  (void)&T::enum_in_struct;
+  switch_test(1);
+  switch_test2();
+  DynamicDLLImportInitVSMangling::switch_test3();
 }
 
 // CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"()
diff --git a/test/CodeGenCXX/microsoft-abi-structors-alias.cpp b/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
index 59ced74..f977556 100644
--- a/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
@@ -22,5 +22,5 @@
 void foo() {
   B b;
 }
-// CHECK-DAG: @"\01??1B@test2@@UAE@XZ" = alias void (%"struct.test2::B"*), void (%"struct.test2::A"*)* @"\01??1A@test2@@UAE@XZ"
+// CHECK-DAG: @"\01??1B@test2@@UAE@XZ" = alias bitcast (void (%"struct.test2::A"*)* @"\01??1A@test2@@UAE@XZ" to void (%"struct.test2::B"*)*)
 }
diff --git a/test/CodeGenCXX/microsoft-abi-structors.cpp b/test/CodeGenCXX/microsoft-abi-structors.cpp
index b79da8d..04227e3 100644
--- a/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -153,7 +153,7 @@
 void foo() {
   C c;
 }
-// DTORS2-LABEL: define weak x86_thiscallcc void @"\01??_EC@dtor_in_second_nvbase@@W3AEPAXI@Z"
+// DTORS2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_EC@dtor_in_second_nvbase@@W3AEPAXI@Z"
 // DTORS2:       (%"struct.dtor_in_second_nvbase::C"* %this, i32 %should_call_delete)
 //      Do an adjustment from B* to C*.
 // DTORS2:   getelementptr i8* %{{.*}}, i32 -4
diff --git a/test/CodeGenCXX/microsoft-abi-thunks.cpp b/test/CodeGenCXX/microsoft-abi-thunks.cpp
index 2be642c..c755b30 100644
--- a/test/CodeGenCXX/microsoft-abi-thunks.cpp
+++ b/test/CodeGenCXX/microsoft-abi-thunks.cpp
@@ -61,13 +61,13 @@
 
 C::C() {}  // Emits vftable and forces thunk generation.
 
-// CODEGEN-LABEL: define weak x86_thiscallcc void @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete)
+// CODEGEN-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete)
 // CODEGEN:   getelementptr i8* {{.*}}, i32 -4
 // FIXME: should actually call _EC, not _GC.
 // CODEGEN:   call x86_thiscallcc void @"\01??_GC@@UAEPAXI@Z"
 // CODEGEN: ret
 
-// CODEGEN-LABEL: define weak x86_thiscallcc void @"\01?public_f@C@@W3AEXXZ"(%struct.C*
+// CODEGEN-LABEL: define linkonce_odr x86_thiscallcc void @"\01?public_f@C@@W3AEXXZ"(%struct.C*
 // CODEGEN:   getelementptr i8* {{.*}}, i32 -4
 // CODEGEN:   call x86_thiscallcc void @"\01?public_f@C@@UAEXXZ"(%struct.C*
 // CODEGEN: ret
@@ -91,7 +91,7 @@
 
 E::E() {}  // Emits vftable and forces thunk generation.
 
-// CODEGEN-LABEL: define weak x86_thiscallcc %struct.C* @"\01?goo@E@@QAEPAUB@@XZ"
+// CODEGEN-LABEL: define weak_odr x86_thiscallcc %struct.C* @"\01?goo@E@@QAEPAUB@@XZ"
 // CODEGEN:   call x86_thiscallcc %struct.C* @"\01?goo@E@@UAEPAUC@@XZ"
 // CODEGEN:   getelementptr inbounds i8* {{.*}}, i32 4
 // CODEGEN: ret
@@ -124,7 +124,7 @@
 
 I::I() {}  // Emits vftable and forces thunk generation.
 
-// CODEGEN-LABEL: define weak x86_thiscallcc %struct.{{[BF]}}* @"\01?goo@I@@QAEPAUB@@XZ"
+// CODEGEN-LABEL: define weak_odr x86_thiscallcc %struct.{{[BF]}}* @"\01?goo@I@@QAEPAUB@@XZ"
 // CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc %struct.F* @"\01?goo@I@@UAEPAUF@@XZ"
 // CODEGEN: %[[ORIG_RET_i8:.*]] = bitcast %struct.F* %[[ORIG_RET]] to i8*
 // CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[ORIG_RET_i8]], i32 4
@@ -152,3 +152,14 @@
 };
 C c;
 }
+
+namespace {
+struct E : D {
+  E();
+  virtual C* goo();
+};
+E::E() {}
+E e;
+// Class with internal linkage has internal linkage thunks.
+// CODEGEN: define internal x86_thiscallcc %struct.C* @"\01?goo@E@?A@@QAEPAUB@@XZ"
+}
diff --git a/test/CodeGenCXX/microsoft-abi-typeid.cpp b/test/CodeGenCXX/microsoft-abi-typeid.cpp
new file mode 100644
index 0000000..4ee004d
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-typeid.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -emit-llvm -O1 -o - -triple=i386-pc-win32 %s | FileCheck %s
+
+struct type_info;
+namespace std { using ::type_info; }
+
+struct V { virtual void f(); };
+struct A : virtual V { A(); };
+
+extern A a;
+extern V v;
+extern int b;
+A* fn();
+
+const std::type_info* test0_typeid() { return &typeid(int); }
+// CHECK-LABEL: define %struct.type_info* @"\01?test0_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:   ret %struct.type_info* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to %struct.type_info*)
+
+const std::type_info* test1_typeid() { return &typeid(A); }
+// CHECK-LABEL: define %struct.type_info* @"\01?test1_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:   ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to %struct.type_info*)
+
+const std::type_info* test2_typeid() { return &typeid(&a); }
+// CHECK-LABEL: define %struct.type_info* @"\01?test2_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:   ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"\01??_R0PAUA@@@8" to %struct.type_info*)
+
+const std::type_info* test3_typeid() { return &typeid(*fn()); }
+// CHECK-LABEL: define %struct.type_info* @"\01?test3_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:        [[CALL:%.*]] = tail call %struct.A* @"\01?fn@@YAPAUA@@XZ"()
+// CHECK-NEXT:   [[CMP:%.*]] = icmp eq %struct.A* [[CALL]], null
+// CHECK-NEXT:   br i1 [[CMP]]
+// CHECK:        tail call i8* @__RTtypeid(i8* null)
+// CHECK-NEXT:   unreachable
+// CHECK:        [[THIS:%.*]] = bitcast %struct.A* [[CALL]] to i8*
+// CHECK-NEXT:   [[VBTBLP:%.*]] = bitcast %struct.A* [[CALL]] to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[VBTBLP]], align 4
+// CHECK-NEXT:   [[VBSLOT:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBITCST:%.*]] = bitcast i8* [[VBSLOT]] to i32*
+// CHECK-NEXT:   [[VBASE_OFFS:%.*]] = load i32* [[VBITCST]], align 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[THIS]], i32 [[VBASE_OFFS]]
+// CHECK-NEXT:   [[RT:%.*]] = tail call i8* @__RTtypeid(i8* [[ADJ]])
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
+// CHECK-NEXT:   ret %struct.type_info* [[RET]]
+
+const std::type_info* test4_typeid() { return &typeid(b); }
+// CHECK: define %struct.type_info* @"\01?test4_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:   ret %struct.type_info* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to %struct.type_info*)
+
+const std::type_info* test5_typeid() { return &typeid(v); }
+// CHECK: define %struct.type_info* @"\01?test5_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:        [[RT:%.*]] = tail call i8* @__RTtypeid(i8* bitcast (%struct.V* @"\01?v@@3UV@@A" to i8*))
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
+// CHECK-NEXT:   ret %struct.type_info* [[RET]]
diff --git a/test/CodeGenCXX/microsoft-abi-vftables.cpp b/test/CodeGenCXX/microsoft-abi-vftables.cpp
new file mode 100644
index 0000000..4368cc7
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=NO-RTTI
+// RUN: %clang_cc1 %s -triple=i386-pc-win32 -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=RTTI
+
+// RTTI-DAG: $"\01??_7S@@6B@" = comdat largest
+// RTTI-DAG: $"\01??_7V@@6B@" = comdat largest
+
+struct S {
+  virtual ~S();
+} s;
+
+// RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4S@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)], comdat $"\01??_7S@@6B@"
+// RTTI-DAG: @"\01??_7S@@6B@" = unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[VTABLE_S]], i32 0, i32 1)
+
+// NO-RTTI-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)]
+
+struct __declspec(dllimport) U {
+  virtual ~U();
+} u;
+
+// RTTI-DAG: @"\01??_7U@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
+
+// NO-RTTI-DAG: @"\01??_7U@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
+
+struct __declspec(dllexport) V {
+  virtual ~V();
+} v;
+
+// RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4V@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)], comdat $"\01??_7V@@6B@"
+// RTTI-DAG: @"\01??_7V@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[VTABLE_V]], i32 0, i32 1)
+
+// NO-RTTI-DAG: @"\01??_7V@@6B@" = weak_odr dllexport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)]
+
+namespace {
+struct W {
+  virtual ~W();
+} w;
+}
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)]
+// RTTI-DAG: @"\01??_7W@?A@@6B@" = unnamed_addr alias internal getelementptr inbounds ([2 x i8*]* @1, i32 0, i32 1)
+
+// NO-RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)]
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
index 5d11896..a6fcdea 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
@@ -23,7 +23,7 @@
 
 D::D() {}  // Forces vftable emission.
 
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ"
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ"
 // CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}}
 // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
 // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4
@@ -34,7 +34,7 @@
 // CHECK: call x86_thiscallcc void @"\01?f@D@@UAEXXZ"(i8* %[[ADJUSTED_i8]])
 // CHECK: ret void
 
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f@D@@$4PPPPPPPI@3AEXXZ"
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPI@3AEXXZ"
 // CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}}
 // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
 // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -8
@@ -63,7 +63,7 @@
 
 G::G() {}  // Forces vftable emission.
 
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f@E@@$R4BA@M@PPPPPPPM@7AEXXZ"(i8*)
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@E@@$R4BA@M@PPPPPPPM@7AEXXZ"(i8*)
 // CHECK: %[[ECX:.*]] = load %struct.E** %{{.*}}
 // CHECK: %[[ECX_i8:.*]] = bitcast %struct.E* %[[ECX]] to i8*
 // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
index 6ef3176..4ce4e9c 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -145,7 +145,7 @@
   // MANGLING-DAG: @"\01??_7X@Test4@@6B@"
 
   // Also check the mangling of the thunk.
-  // MANGLING-DAG: define weak x86_thiscallcc void @"\01?f@C@@WPPPPPPPI@AEXXZ"
+  // MANGLING-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@C@@WPPPPPPPI@AEXXZ"
 };
 
 X::X() {}
diff --git a/test/CodeGenCXX/microsoft-no-rtti-data.cpp b/test/CodeGenCXX/microsoft-no-rtti-data.cpp
new file mode 100644
index 0000000..d4002c2
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-no-rtti-data.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -fno-rtti-data -triple=i386-pc-win32 -o - -emit-llvm | FileCheck %s
+
+// vftable shouldn't have RTTI data in it.
+// CHECK: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)]
+
+struct type_info;
+namespace std { using ::type_info; }
+
+struct S {
+  virtual ~S();
+} s;
+
+struct U : S {
+  virtual ~U();
+};
+
+extern S *getS();
+
+const std::type_info &ti = typeid(*getS());
+const U &u = dynamic_cast<U &>(*getS());
+// CHECK: call i8* @__RTDynamicCast(i8* %{{.+}}, i32 0, i8* bitcast ({{.*}} @"\01??_R0?AUS@@@8" to i8*), i8* bitcast ({{.*}} @"\01??_R0?AUU@@@8" to i8*), i32 1)
diff --git a/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp b/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
index 7c94ea0..92e704a 100644
--- a/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
+++ b/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips-unknown-linux-gnu < %s | FileCheck --check-prefix=O32 %s
 // RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips64-unknown-linux-gnu -target-abi n32 < %s | FileCheck --check-prefix=N32 %s
-// RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips64-unknown-linux-gnu -target-abi 64 < %s | FileCheck --check-prefix=N64 %s
+// RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips64-unknown-linux-gnu -target-abi n64 < %s | FileCheck --check-prefix=N64 %s
 
 // Test that the size_t is correct for the ABI. It's not sufficient to be the
 // correct size, it must be the same type for correct name mangling.
diff --git a/test/CodeGenCXX/ms_wide_predefined_expr.cpp b/test/CodeGenCXX/ms_wide_predefined_expr.cpp
index b6af519..3949d39 100644
--- a/test/CodeGenCXX/ms_wide_predefined_expr.cpp
+++ b/test/CodeGenCXX/ms_wide_predefined_expr.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -fms-extensions -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s
 
-// CHECK: @"L__FUNCTION__.?func@@YAXXZ" = private constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], align 2
+// CHECK: @"\01??_C@_19DPFBEKIN@?$AAf?$AAu?$AAn?$AAc?$AA?$AA@" = linkonce_odr unnamed_addr constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], align 2
 
 void wprint(const wchar_t*);
 
diff --git a/test/CodeGenCXX/new-array-init.cpp b/test/CodeGenCXX/new-array-init.cpp
index 0e925c0a..65123ea 100644
--- a/test/CodeGenCXX/new-array-init.cpp
+++ b/test/CodeGenCXX/new-array-init.cpp
@@ -6,8 +6,8 @@
   // CHECK: store i32 1
   // CHECK: store i32 2
   // CHECK: store i32 3
-  // CHECK: icmp eq i32*
-  // CHECK-NEXT: br i1
+  // CHECK: sub {{.*}}, 12
+  // CHECK: call void @llvm.memset
   new int[n] { 1, 2, 3 };
 }
 
@@ -31,3 +31,18 @@
   new int[4] { 1, 2, 3 };
   // CHECK: ret void
 }
+
+// CHECK-LABEL: define void @_Z22check_array_value_initv
+void check_array_value_init() {
+  struct S;
+  new (int S::*[3][4][5]) ();
+
+  // CHECK: call noalias i8* @_Zna{{.}}(i{{32 240|64 480}})
+  // CHECK: getelementptr inbounds i{{32|64}}* {{.*}}, i{{32|64}} 60
+
+  // CHECK: phi
+  // CHECK: store i{{32|64}} -1,
+  // CHECK: getelementptr inbounds i{{32|64}}* {{.*}}, i{{32|64}} 1
+  // CHECK: icmp eq
+  // CHECK: br i1
+}
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index 26db842..862161b 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -2,6 +2,9 @@
 
 typedef __typeof__(sizeof(0)) size_t;
 
+// Declare an 'operator new' template to tickle a bug in __builtin_operator_new.
+template<typename T> void *operator new(size_t, int (*)(T));
+
 // Ensure that this declaration doesn't cause operator new to lose its
 // 'noalias' attribute.
 void *operator new[](size_t);
@@ -33,7 +36,6 @@
 void operator delete(void *, const std::nothrow_t &) throw();
 void operator delete[](void *, const std::nothrow_t &) throw();
 
-
 void t2(int* a) {
   int* b = new (a) int;
 }
@@ -326,6 +328,15 @@
   }
 }
 
+namespace builtins {
+  // CHECK-LABEL: define void @_ZN8builtins1fEv
+  void f() {
+    // CHECK: call noalias i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW]]
+    // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE]]
+    __builtin_operator_delete(__builtin_operator_new(4));
+  }
+}
+
 // CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin {{.*[}]}}
 // CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}}
 
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index aa6b122..2bbf277 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -169,7 +169,7 @@
   return a;
   // CHECK:      [[A:%.*]] = alloca [[X:%.*]], align 8
   // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]])
-  // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]])
+  // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* nonnull [[A]])
   // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]])
   // CHECK-NEXT: ret void
 }
diff --git a/test/CodeGenCXX/pod-member-memcpys.cpp b/test/CodeGenCXX/pod-member-memcpys.cpp
index 5c79568..396129e 100644
--- a/test/CodeGenCXX/pod-member-memcpys.cpp
+++ b/test/CodeGenCXX/pod-member-memcpys.cpp
@@ -108,59 +108,59 @@
 CALL_AO(PackedMembers)
 
 // Basic copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic*)
+// CHECK-LABEL: define linkonce_odr nonnull %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call nonnull %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.Basic*
 
 // PODMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember*)
+// CHECK-LABEL: define linkonce_odr nonnull %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call nonnull %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.PODMember*
 
 // PODLikeMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
+// CHECK-LABEL: define linkonce_odr nonnull %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call nonnull %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.PODLikeMember*
 
 // ArrayMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
+// CHECK-LABEL: define linkonce_odr nonnull %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call nonnull %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
 // CHECK: ret %struct.ArrayMember*
 
 // VolatileMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
+// CHECK-LABEL: define linkonce_odr nonnull %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: load volatile i32* {{.*}}, align 4
 // CHECK: store volatile i32 {{.*}}, align 4
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call nonnull %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.VolatileMember*
 
 // BitfieldMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
+// CHECK-LABEL: define linkonce_odr nonnull %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call nonnull %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
 // CHECK: ret %struct.BitfieldMember*
 
 // InnerClass copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
+// CHECK-LABEL: define linkonce_odr nonnull %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call nonnull %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.InnerClassMember*
 
 // PackedMembers copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*)
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK-LABEL: define linkonce_odr nonnull %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* nonnull)
+// CHECK: call nonnull %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
 // CHECK: ret %struct.PackedMembers*
 
@@ -184,21 +184,21 @@
 CALL_CC(Basic)
 
 // Basic copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic*)
+// CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret void
 
 // PODMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret void
 
 // PODLikeMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
 // CHECK: invoke void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
@@ -207,14 +207,14 @@
 // CHECK: invoke void @_ZN7PODLikeD1Ev
 
 // ArrayMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
 // CHECK: ret void
 
 // VolatileMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: load volatile i32* {{.*}}, align 4
 // CHECK: store volatile i32 {{.*}}, align 4
@@ -223,34 +223,34 @@
 // CHECK: ret void
 
 // BitfieldMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
 // CHECK: ret void
 
 // InnerClass copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret void
 
 // ReferenceMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember* nonnull)
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
 // CHECK: ret void
 
 // BitfieldMember2 copy-constructor:
-// CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2*)
+// CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2* nonnull)
 // CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4, i1 false)
 // CHECK-2: call void @_ZN6NonPODC1ERKS_
 // CHECK-2: ret void
 
 // PackedMembers copy-assignment:
-// CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*)
+// CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* nonnull)
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
 // CHECK: ret void
diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp
index f0199c8..866fba2 100644
--- a/test/CodeGenCXX/pointers-to-data-members.cpp
+++ b/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -202,7 +202,7 @@
     bool member;
   };
 
-  // CHECK-LABEL: define i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b
+  // CHECK-LABEL: define nonnull i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b
   bool &f(X &x, bool X::*member) {
     // CHECK: {{bitcast.* to i8\*}}
     // CHECK-NEXT: getelementptr inbounds i8*
diff --git a/test/CodeGenCXX/reference-cast.cpp b/test/CodeGenCXX/reference-cast.cpp
index 60ea393..0596ceb 100644
--- a/test/CodeGenCXX/reference-cast.cpp
+++ b/test/CodeGenCXX/reference-cast.cpp
@@ -3,7 +3,7 @@
 // PR6024
 extern int i;
 
-// CHECK: define i32* @_Z16lvalue_noop_castv() [[NUW:#[0-9]+]]
+// CHECK: define nonnull i32* @_Z16lvalue_noop_castv() [[NUW:#[0-9]+]]
 const int &lvalue_noop_cast() {
   if (i == 0)
     // CHECK: store i32 17, i32*
@@ -15,7 +15,7 @@
   return 17;
 }
 
-// CHECK-LABEL: define i16* @_Z20lvalue_integral_castv() 
+// CHECK-LABEL: define nonnull i16* @_Z20lvalue_integral_castv() 
 const short &lvalue_integral_cast() {
   if (i == 0)
     // CHECK: store i16 17, i16*
@@ -27,7 +27,7 @@
   return 17;
 }
 
-// CHECK-LABEL: define i16* @_Z29lvalue_floating_integral_castv()
+// CHECK-LABEL: define nonnull i16* @_Z29lvalue_floating_integral_castv()
 const short &lvalue_floating_integral_cast() {
   if (i == 0)
     // CHECK: store i16 17, i16*
@@ -39,7 +39,7 @@
   return 17.5;
 }
 
-// CHECK-LABEL: define float* @_Z29lvalue_integral_floating_castv()
+// CHECK-LABEL: define nonnull float* @_Z29lvalue_integral_floating_castv()
 const float &lvalue_integral_floating_cast() {
   if (i == 0)
     // CHECK: store float 1.700000e+{{0*}}1, float*
@@ -51,7 +51,7 @@
   return 17;
 }
 
-// CHECK-LABEL: define float* @_Z20lvalue_floating_castv()
+// CHECK-LABEL: define nonnull float* @_Z20lvalue_floating_castv()
 const float &lvalue_floating_cast() {
   if (i == 0)
     // CHECK: store float 1.700000e+{{0*}}1, float*
@@ -65,7 +65,7 @@
 
 int get_int();
 
-// CHECK-LABEL: define i8* @_Z24lvalue_integer_bool_castv()
+// CHECK-LABEL: define nonnull i8* @_Z24lvalue_integer_bool_castv()
 const bool &lvalue_integer_bool_cast() {
   if (i == 0)
     // CHECK: call i32 @_Z7get_intv()
@@ -82,7 +82,7 @@
 
 float get_float();
 
-// CHECK-LABEL: define i8* @_Z25lvalue_floating_bool_castv()
+// CHECK-LABEL: define nonnull i8* @_Z25lvalue_floating_bool_castv()
 const bool &lvalue_floating_bool_cast() {
   if (i == 0)
     // CHECK: call float @_Z9get_floatv()
@@ -107,7 +107,7 @@
 pm get_pointer_to_member_data();
 pmf get_pointer_to_member_function();
 
-// CHECK-LABEL: define i8* @_Z26lvalue_ptrmem_to_bool_castv()
+// CHECK-LABEL: define nonnull i8* @_Z26lvalue_ptrmem_to_bool_castv()
 const bool &lvalue_ptrmem_to_bool_cast() {
   if (i == 0)
     // CHECK: call i64 @_Z26get_pointer_to_member_datav()
@@ -125,7 +125,7 @@
   return get_pointer_to_member_data();
 }
 
-// CHECK-LABEL: define i8* @_Z27lvalue_ptrmem_to_bool_cast2v
+// CHECK-LABEL: define nonnull i8* @_Z27lvalue_ptrmem_to_bool_cast2v
 const bool &lvalue_ptrmem_to_bool_cast2() {
   if (i == 0)
     // CHECK: {{call.*_Z30get_pointer_to_member_functionv}}
diff --git a/test/CodeGenCXX/rvalue-references.cpp b/test/CodeGenCXX/rvalue-references.cpp
index 2e0fa82..6c723b8 100644
--- a/test/CodeGenCXX/rvalue-references.cpp
+++ b/test/CodeGenCXX/rvalue-references.cpp
@@ -7,8 +7,8 @@
 
 B &getB();
 
-// CHECK-LABEL: define %struct.A* @_Z4getAv()
-// CHECK: call %struct.B* @_Z4getBv()
+// CHECK-LABEL: define nonnull %struct.A* @_Z4getAv()
+// CHECK: call nonnull %struct.B* @_Z4getBv()
 // CHECK-NEXT: bitcast %struct.B*
 // CHECK-NEXT: getelementptr inbounds i8*
 // CHECK-NEXT: bitcast i8* {{.*}} to %struct.A*
@@ -19,17 +19,17 @@
 int &&getIntXValue();
 int getIntPRValue();
 
-// CHECK-LABEL: define i32* @_Z2f0v()
-// CHECK: call i32* @_Z12getIntLValuev()
+// CHECK-LABEL: define nonnull i32* @_Z2f0v()
+// CHECK: call nonnull i32* @_Z12getIntLValuev()
 // CHECK-NEXT: ret i32*
 int &&f0() { return static_cast<int&&>(getIntLValue()); }
 
-// CHECK-LABEL: define i32* @_Z2f1v()
-// CHECK: call i32* @_Z12getIntXValuev()
+// CHECK-LABEL: define nonnull i32* @_Z2f1v()
+// CHECK: call nonnull i32* @_Z12getIntXValuev()
 // CHECK-NEXT: ret i32*
 int &&f1() { return static_cast<int&&>(getIntXValue()); }
 
-// CHECK-LABEL: define i32* @_Z2f2v
+// CHECK-LABEL: define nonnull i32* @_Z2f2v
 // CHECK: call i32 @_Z13getIntPRValuev()
 // CHECK-NEXT: store i32 {{.*}}, i32*
 // CHECK-NEXT: ret i32*
@@ -95,7 +95,7 @@
   };
 
   // CHECK-LABEL:    define void @_ZN5test11BC2Ei(
-  // CHECK:      [[T0:%.*]] = call i32* @_ZN5test14moveERi(
+  // CHECK:      [[T0:%.*]] = call nonnull i32* @_ZN5test14moveERi(
   // CHECK-NEXT: [[T1:%.*]] = load i32* [[T0]]
   // CHECK-NEXT: call void @_ZN5test11AC1Ei({{.*}}, i32 [[T1]])
   // CHECK-NEXT: ret void
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index 1f476ee..37286c2 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -27,6 +27,21 @@
   // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12
 }
 
+namespace PR20227 {
+  struct A { ~A(); };
+  struct B { virtual ~B(); };
+  struct C : B {};
+
+  A &&a = dynamic_cast<A&&>(A{});
+  // CHECK: @_ZGRN7PR202271aE_ = private global
+
+  B &&b = dynamic_cast<C&&>(dynamic_cast<B&&>(C{}));
+  // CHECK: @_ZGRN7PR202271bE_ = private global
+
+  B &&c = static_cast<C&&>(static_cast<B&&>(C{}));
+  // CHECK: @_ZGRN7PR202271cE_ = private global
+}
+
 struct A {
   A();
   ~A();
@@ -310,7 +325,7 @@
 void g() {
   // CHECK: call void @_ZN3T121AC1Ev
   // CHECK-NEXT: call i32 @_ZN3T121A1fEv(
-  // CHECK-NEXT: call i32* @_ZN3T121fEi(
+  // CHECK-NEXT: call nonnull i32* @_ZN3T121fEi(
   // CHECK-NEXT: call void @_ZN3T121AD1Ev(
   int& i = f(A().f());
 }
@@ -325,7 +340,7 @@
   struct D;
   D& zed(B);
   void foobar() {
-    // CHECK: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
+    // CHECK: call nonnull %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
     zed(foo);
   }
 }
@@ -412,10 +427,10 @@
     // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
 
     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
-    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* [[X:%.*]])
+    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* nonnull [[X:%.*]])
     A i = (c ? A() : x);
 
-    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* [[X]])
+    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* nonnull [[X]])
     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
     A j = (c ? x : A());
 
@@ -435,10 +450,10 @@
   A test3(int v, A x) {
     if (v < 5)
     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
-    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X:%.*]])
+    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* nonnull [[X:%.*]])
       return (v < 0 ? A() : x);
     else
-    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X]])
+    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* nonnull [[X]])
     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
       return (v > 10 ? x : A());
 
@@ -456,7 +471,7 @@
     // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i64 0, i64 0
     // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
     // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]]* [[XS0]], i64 1
-    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]])
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* nonnull [[X]])
     A xs[] = { A(), x };
 
     // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
@@ -483,7 +498,7 @@
 
     // CHECK:      call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0
-    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* nonnull [[AM]])
     // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
@@ -491,13 +506,13 @@
 
     // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0
-    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* nonnull [[AM]])
     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
     A x = B().a;
 
     // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0
-    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* nonnull [[AM]])
     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
     return B().a;
 
diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp
index 7e81141..549aef0 100644
--- a/test/CodeGenCXX/throw-expressions.cpp
+++ b/test/CodeGenCXX/throw-expressions.cpp
@@ -80,3 +80,35 @@
   // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE
   // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
 }
+
+// CHECK-LABEL: define void @_Z5test7b(
+void test7(bool cond) {
+  // CHECK: br i1
+  //
+  // x.true:
+  // CHECK: call void @__cxa_throw(
+  // CHECK-NEXT: unreachable
+  //
+  // x.false:
+  // CHECK: br label
+  //
+  // end:
+  // CHECK: ret void
+  cond ? throw test7 : val;
+}
+
+// CHECK-LABEL: define nonnull i32* @_Z5test8b(
+int &test8(bool cond) {
+  // CHECK: br i1
+  //
+  // x.true:
+  // CHECK: br label
+  //
+  // x.false:
+  // CHECK: call void @__cxa_throw(
+  // CHECK-NEXT: unreachable
+  //
+  // end:
+  // CHECK: ret i32* @val
+  return cond ? val : ((throw "foo"));
+}
diff --git a/test/CodeGenCXX/tls-init-funcs.cpp b/test/CodeGenCXX/tls-init-funcs.cpp
index 17299dc..99fe75f 100644
--- a/test/CodeGenCXX/tls-init-funcs.cpp
+++ b/test/CodeGenCXX/tls-init-funcs.cpp
@@ -2,6 +2,7 @@
 
 // CHECK: @a = internal thread_local global
 // CHECK: @_tlv_atexit({{.*}}@_ZN1AD1Ev
+// CHECK: define weak hidden {{.*}} @_ZTW1a
 
 struct A {
   ~A();
diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp
index 46a446b..3e7fa82 100644
--- a/test/CodeGenCXX/virtual-destructor-calls.cpp
+++ b/test/CodeGenCXX/virtual-destructor-calls.cpp
@@ -17,8 +17,8 @@
 // CHECK: @_ZN1BD1Ev = alias {{.*}} @_ZN1BD2Ev
 
 // (aliases from C)
-// CHECK: @_ZN1CD1Ev = alias {{.*}} @_ZN1BD2Ev
-// CHECK: @_ZN1CD2Ev = alias {{.*}} @_ZN1BD2Ev
+// CHECK: @_ZN1CD1Ev = alias {{.*}} @_ZN1CD2Ev
+// CHECK: @_ZN1CD2Ev = alias bitcast {{.*}} @_ZN1BD2Ev
 
 // Base dtor: actually calls A's base dtor.
 // CHECK-LABEL: define void @_ZN1BD2Ev(%struct.B* %this) unnamed_addr
diff --git a/test/CodeGenCXX/volatile.cpp b/test/CodeGenCXX/volatile.cpp
index 38c8829..b2dd36e 100644
--- a/test/CodeGenCXX/volatile.cpp
+++ b/test/CodeGenCXX/volatile.cpp
@@ -15,7 +15,7 @@
   void test(A t) {
     // CHECK:      [[ARR:%.*]] = load [[A:%.*]]** @_ZN5test05arrayE, align 8
     // CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [[A]]* [[ARR]], i64 0
-    // CHECK-NEXT: [[TMP:%.*]] = call [[A]]* @_ZNV5test01AaSERVKS0_([[A]]* [[IDX]], [[A]]* [[T:%.*]])
+    // CHECK-NEXT: [[TMP:%.*]] = call nonnull [[A]]* @_ZNV5test01AaSERVKS0_([[A]]* [[IDX]], [[A]]* nonnull [[T:%.*]])
     // CHECK-NEXT: ret void
     array[0] = t;
   }
diff --git a/test/CodeGenCXX/windows-itanium-exceptions.cpp b/test/CodeGenCXX/windows-itanium-exceptions.cpp
new file mode 100644
index 0000000..e2c4190
--- /dev/null
+++ b/test/CodeGenCXX/windows-itanium-exceptions.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -emit-llvm -triple thumbv7-windows-itanium -fexceptions -fcxx-exceptions %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fexceptions -fcxx-exceptions %s -o - | FileCheck %s
+// REQUIRES: asserts
+
+void except() {
+  throw 32;
+}
+
+void attempt() {
+  try { except(); } catch (...) { }
+}
+
+// CHECK: @_ZTIi = external constant i8*
+
+// CHECK: define {{.*}}void @_Z6exceptv() {{.*}} {
+// CHECK:   %exception = call {{.*}}i8* @__cxa_allocate_exception(i32 4)
+// CHECK:   %0 = bitcast i8* %exception to i32*
+// CHECK:   store i32 32, i32* %0
+// CHECK:   call {{.*}}void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+// CHECK:   unreachable
+// CHECK: }
+
+// CHECK: define {{.*}}void @_Z7attemptv() {{.*}} {
+// CHECK:   %exn.slot = alloca i8*
+// CHECK:   %ehselector.slot = alloca i32
+// CHECK:   invoke {{.*}}void @_Z6exceptv()
+// CHECK:     to label %invoke.cont unwind label %lpad
+// CHECK: invoke.cont:
+// CHECK:    br label %try.cont
+// CHECK: lpad:
+// CHECK:    %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK:      catch i8* null
+// CHECK:    %1 = extractvalue { i8*, i32 } %0, 0
+// CHECK:    store i8* %1, i8** %exn.slot
+// CHECK:    %2 = extractvalue { i8*, i32 } %0, 1
+// CHECK:    store i32 %2, i32* %ehselector.slot
+// CHECK:    br label %catch
+// CHECK: catch:
+// CHECK:    %exn = load i8** %exn.slot
+// CHECK:    %3 = call {{.*}}i8* @__cxa_begin_catch(i8* %{{2|exn}})
+// CHECK:    call {{.*}}void @__cxa_end_catch()
+// CHECK:    br label %try.cont
+// CHECK: try.cont:
+// CHECK:    ret void
+// CHECK: }
+
+
diff --git a/test/CodeGenObjC/image-info.m b/test/CodeGenObjC/image-info.m
index 030bcae..49f5d90 100644
--- a/test/CodeGenObjC/image-info.m
+++ b/test/CodeGenObjC/image-info.m
@@ -4,14 +4,14 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
 // RUN: FileCheck --check-prefix CHECK-NONFRAGILE < %t %s
 
-// CHECK-FRAGILE:      !llvm.module.flags = !{!0, !1, !2, !3}
-// CHECK-FRAGILE:      !0 = metadata !{i32 1, metadata !"Objective-C Version", i32 1}
-// CHECK-FRAGILE-NEXT: !1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
-// CHECK-FRAGILE-NEXT: !2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__OBJC, __image_info,regular"}
-// CHECK-FRAGILE-NEXT: !3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
+// CHECK-FRAGILE:      !llvm.module.flags = !{{{.*}}}
+// CHECK-FRAGILE:      !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Version", i32 1}
+// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
+// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__OBJC, __image_info,regular"}
+// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
 
-// CHECK-NONFRAGILE:      !llvm.module.flags = !{!0, !1, !2, !3}
-// CHECK-NONFRAGILE:      !0 = metadata !{i32 1, metadata !"Objective-C Version", i32 2}
-// CHECK-NONFRAGILE-NEXT: !1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
-// CHECK-NONFRAGILE-NEXT: !2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
-// CHECK-NONFRAGILE-NEXT: !3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
+// CHECK-NONFRAGILE:      !llvm.module.flags = !{{{.*}}}
+// CHECK-NONFRAGILE:      !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Version", i32 2}
+// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
+// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
+// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
diff --git a/test/CodeGenObjC/ivar-base-as-invariant-load.m b/test/CodeGenObjC/ivar-base-as-invariant-load.m
index 19dc658..061fea3 100644
--- a/test/CodeGenObjC/ivar-base-as-invariant-load.m
+++ b/test/CodeGenObjC/ivar-base-as-invariant-load.m
@@ -23,7 +23,7 @@
 
 @end
 
-// CHECK: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
-// CHECK: [[T2:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
-// CHECK: [[T3:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
-
+// CHECK: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load ![[MD_NUM:[0-9]+]]
+// CHECK: [[T2:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load ![[MD_NUM]]
+// CHECK: [[T3:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load ![[MD_NUM]]
+//
diff --git a/test/CodeGenObjC/return-objc-object.mm b/test/CodeGenObjC/return-objc-object.mm
index 95cce23..25ed202 100644
--- a/test/CodeGenObjC/return-objc-object.mm
+++ b/test/CodeGenObjC/return-objc-object.mm
@@ -15,5 +15,5 @@
   f();
   f1();
 }
-// CHECK: call %0* @_Z1fv()
-// CHECK: call %0* @_Z2f1v()  
+// CHECK: call nonnull %0* @_Z1fv()
+// CHECK: call nonnull %0* @_Z2f1v()  
diff --git a/test/CodeGenObjC/weak-metaclass-visibility.m b/test/CodeGenObjC/weak-metaclass-visibility.m
index 1f76197..128f881 100644
--- a/test/CodeGenObjC/weak-metaclass-visibility.m
+++ b/test/CodeGenObjC/weak-metaclass-visibility.m
@@ -3,6 +3,7 @@
 
 @interface NSObject 
 - (void) finalize;
++ (void) class;
 @end
 
 __attribute__((availability(macosx,introduced=9876.5)))
@@ -31,3 +32,14 @@
 // CHECK: @"OBJC_METACLASS_$_MyClass" = global %struct._class_t
 // CHECK: @"OBJC_CLASS_$_NSObject" = external global %struct._class_t
 
+// rdar://16529125
+__attribute__((weak_import))
+@interface NSURLQueryItem : NSObject
+@end
+
+@implementation NSURLQueryItem (hax)
++(void)classmethod { [super class]; }
+@end
+
+// CHECK: @"OBJC_METACLASS_$_NSURLQueryItem" = extern_weak global
+// CHECK: @"OBJC_CLASS_$_NSURLQueryItem" = extern_weak global
diff --git a/test/CodeGenObjCXX/arc-blocks.mm b/test/CodeGenObjCXX/arc-blocks.mm
index cc3e831..4fc3885 100644
--- a/test/CodeGenObjCXX/arc-blocks.mm
+++ b/test/CodeGenObjCXX/arc-blocks.mm
@@ -38,7 +38,7 @@
   // CHECK-NEXT: load
   // CHECK-NEXT: [[T2:%.*]] = bitcast i8* {{.*}} to [[BYREF_A]]*
   // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_A]]* [[T2]], i32 0, i32 7
-  // CHECK-NEXT: call void @_ZN5test01AC1ERKS0_([[A]]* [[T1]], [[A]]* [[T3]])
+  // CHECK-NEXT: call void @_ZN5test01AC1ERKS0_([[A]]* [[T1]], [[A]]* nonnull [[T3]])
   // CHECK-NEXT: ret void
 
   // CHECK:    define internal void [[DISPOSE_HELPER]](
diff --git a/test/CodeGenObjCXX/arc-move.mm b/test/CodeGenObjCXX/arc-move.mm
index 0a8286d..7e90388 100644
--- a/test/CodeGenObjCXX/arc-move.mm
+++ b/test/CodeGenObjCXX/arc-move.mm
@@ -33,7 +33,7 @@
 
 // CHECK-LABEL: define void @_Z12library_moveRU8__strongP11objc_objectS2_
 void library_move(__strong id &x, __strong id &y) {
-  // CHECK: call i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
+  // CHECK: call nonnull i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
   // CHECK: load i8**
   // CHECK: store i8* null, i8**
   // CHECK: load i8***
@@ -46,7 +46,7 @@
 
 // CHECK-LABEL: define void @_Z12library_moveRU8__strongP11objc_object
 void library_move(__strong id &y) {
-  // CHECK: [[Y:%[a-zA-Z0-9]+]] = call i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
+  // CHECK: [[Y:%[a-zA-Z0-9]+]] = call nonnull i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
   // Load the object
   // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8** [[Y]]
   // Null out y
@@ -65,7 +65,7 @@
 // CHECK-LABEL: define void @_Z10const_moveRKU8__strongP11objc_object(
 void const_move(const __strong id &x) {
   // CHECK:      [[Y:%.*]] = alloca i8*,
-  // CHECK:      [[X:%.*]] = call i8** @_Z4moveIRKU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_(
+  // CHECK:      [[X:%.*]] = call nonnull i8** @_Z4moveIRKU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_(
   // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
   // CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
diff --git a/test/CodeGenObjCXX/arc-special-member-functions.mm b/test/CodeGenObjCXX/arc-special-member-functions.mm
index 49077ff..c8c6dd7 100644
--- a/test/CodeGenObjCXX/arc-special-member-functions.mm
+++ b/test/CodeGenObjCXX/arc-special-member-functions.mm
@@ -91,7 +91,7 @@
 }
 
 // Implicitly-generated copy assignment operator for ObjCBlockMember
-// CHECK:    define linkonce_odr {{%.*}}* @_ZN15ObjCBlockMemberaSERKS_(
+// CHECK:    define linkonce_odr nonnull {{%.*}}* @_ZN15ObjCBlockMemberaSERKS_(
 // CHECK:      [[T0:%.*]] = getelementptr inbounds [[T:%.*]]* {{%.*}}, i32 0, i32 0
 // CHECK-NEXT: [[T1:%.*]] = load i32 (i32)** [[T0]], align 8
 // CHECK-NEXT: [[T2:%.*]] = bitcast i32 (i32)* [[T1]] to i8*
diff --git a/test/CodeGenObjCXX/implicit-copy-assign-operator.mm b/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
index 88837c1..f9cdcb4 100644
--- a/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
+++ b/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
@@ -43,7 +43,7 @@
   d1 = d2;
 }
 
-// CHECK-OBJ-LABEL: define linkonce_odr %struct.D* @_ZN1DaSERS_
+// CHECK-OBJ-LABEL: define linkonce_odr nonnull %struct.D* @_ZN1DaSERS_
 // CHECK-OBJ: {{call.*_ZN1AaSERS_}}
 // CHECK-OBJ: {{call.*_ZN1BaSERS_}}
 // CHECK-OBJ: {{call.*_ZN1CaSERKS_}}
diff --git a/test/CodeGenObjCXX/implicit-copy-constructor.mm b/test/CodeGenObjCXX/implicit-copy-constructor.mm
index 6dbd39e..d279a6b 100644
--- a/test/CodeGenObjCXX/implicit-copy-constructor.mm
+++ b/test/CodeGenObjCXX/implicit-copy-constructor.mm
@@ -41,7 +41,7 @@
   D d2(d);
 }
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D*) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D* nonnull) unnamed_addr
 // CHECK: call void @_ZN1AC1Ev
 // CHECK: call void @_ZN1CC2ERS_1A
 // CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenObjCXX/lvalue-reference-getter.mm b/test/CodeGenObjCXX/lvalue-reference-getter.mm
index 83d3b93..fcf9b29 100644
--- a/test/CodeGenObjCXX/lvalue-reference-getter.mm
+++ b/test/CodeGenObjCXX/lvalue-reference-getter.mm
@@ -24,5 +24,5 @@
 // CHECK: [[SELF:%.*]] = alloca [[T6:%.*]]*, align
 // CHECK: [[T0:%.*]] = load {{.*}}* [[SELF]], align
 // CHECK: [[T1:%.*]] = load {{.*}}* @"\01L_OBJC_SELECTOR_REFERENCES_"
-// CHECK: [[C:%.*]] = call %struct.SetSection* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK: call i32* @_ZN10SetSection2atEi(%struct.SetSection* [[C]]
+// CHECK: [[C:%.*]] = call nonnull %struct.SetSection* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: call nonnull i32* @_ZN10SetSection2atEi(%struct.SetSection* [[C]]
diff --git a/test/CodeGenObjCXX/message-reference.mm b/test/CodeGenObjCXX/message-reference.mm
index 0d1bbc7..37230d1 100644
--- a/test/CodeGenObjCXX/message-reference.mm
+++ b/test/CodeGenObjCXX/message-reference.mm
@@ -15,6 +15,6 @@
 }
 @end
 
-// CHECK: [[T:%.*]] = call i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: [[T:%.*]] = call nonnull i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
 // CHECK: [[U:%.*]] = load i32* [[T]]
 // CHECK  [[V:%.*]] = icmp eq i32 [[U]], 0
diff --git a/test/CodeGenObjCXX/property-dot-reference.mm b/test/CodeGenObjCXX/property-dot-reference.mm
index be6742a..01b41a5 100644
--- a/test/CodeGenObjCXX/property-dot-reference.mm
+++ b/test/CodeGenObjCXX/property-dot-reference.mm
@@ -11,7 +11,7 @@
 
 @implementation TNodeIconAndNameCell     
 - (const TFENode&) node {
-// CHECK: call %struct.TFENode* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: call nonnull %struct.TFENode* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
 // CHECK-NEXT: call void @_ZNK7TFENode6GetURLEv(%struct.TFENode* %{{.*}})
 	self.node.GetURL();
 }	// expected-warning {{control reaches end of non-void function}}
@@ -27,12 +27,12 @@
 - (const X&) target;
 @end
 void f1(A *a) {
-// CHECK: [[PRP:%.*]] = call %struct.X* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK-NEXT:call void @_Z2f0RK1X(%struct.X* [[PRP]])
+// CHECK: [[PRP:%.*]] = call nonnull %struct.X* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK-NEXT:call void @_Z2f0RK1X(%struct.X* nonnull [[PRP]])
   f0(a.target);
 
-// CHECK: [[MSG:%.*]] = call %struct.X* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK-NEXT:call void @_Z2f0RK1X(%struct.X* [[MSG]])
+// CHECK: [[MSG:%.*]] = call nonnull %struct.X* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK-NEXT:call void @_Z2f0RK1X(%struct.X* nonnull [[MSG]])
   f0([a target]);
 }
 
diff --git a/test/CodeGenObjCXX/property-lvalue-capture.mm b/test/CodeGenObjCXX/property-lvalue-capture.mm
index a4024fd..911bdbe 100644
--- a/test/CodeGenObjCXX/property-lvalue-capture.mm
+++ b/test/CodeGenObjCXX/property-lvalue-capture.mm
@@ -24,12 +24,12 @@
 }
 @end
 
-// CHECK:   [[TWO:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", !invariant.load !5
+// CHECK:   [[TWO:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", !invariant.load ![[MD_NUM:[0-9]+]]
 // CHECK:   [[THREE:%.*]] = bitcast [[ONET:%.*]]* [[ONE:%.*]] to i8*
-// CHECK:   [[CALL:%.*]] = call %struct.Quad2* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct.Quad2* (i8*, i8*)*)(i8* [[THREE]], i8* [[TWO]])
-// CHECK:   [[FOUR:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2", !invariant.load !5
+// CHECK:   [[CALL:%.*]] = call nonnull %struct.Quad2* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct.Quad2* (i8*, i8*)*)(i8* [[THREE]], i8* [[TWO]])
+// CHECK:   [[FOUR:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2", !invariant.load ![[MD_NUM]]
 // CHECK:   [[FIVE:%.*]] = bitcast [[ONET]]* [[ZERO:%.*]] to i8*
-// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.Quad2*)*)(i8* [[FIVE]], i8* [[FOUR]], %struct.Quad2* [[CALL]])
+// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.Quad2*)*)(i8* [[FIVE]], i8* [[FOUR]], %struct.Quad2* nonnull [[CALL]])
 
 
 struct A {
@@ -47,7 +47,7 @@
 }
 
 // CHECK:   [[ONE1:%.*]] = load %struct.A** [[AADDR:%.*]], align 8
-// CHECK:   [[TWO1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_5", !invariant.load !5
+// CHECK:   [[TWO1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_5", !invariant.load ![[MD_NUM]]
 // CHECK:   [[THREE1:%.*]] = bitcast [[TWOT:%.*]]* [[ZERO1:%.*]] to i8*
-// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.A*)*)(i8* [[THREE1]], i8* [[TWO1]], %struct.A* [[ONE1]])
+// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.A*)*)(i8* [[THREE1]], i8* [[TWO1]], %struct.A* nonnull [[ONE1]])
 // CHECK:   store %struct.A* [[ONE1]], %struct.A** [[RESULT:%.*]], align 8
diff --git a/test/CodeGenObjCXX/property-object-reference-2.mm b/test/CodeGenObjCXX/property-object-reference-2.mm
index 542967c..4142967 100644
--- a/test/CodeGenObjCXX/property-object-reference-2.mm
+++ b/test/CodeGenObjCXX/property-object-reference-2.mm
@@ -33,7 +33,7 @@
 // CHECK: [[TWO:%.*]] = load %struct.TCPPObject** [[ADDR:%.*]], align 8
 // CHECK: [[THREE:%.*]] = load %struct.TCPPObject** [[ADDR1:%.*]], align 8
 // CHECK: [[CALL:%.*]] = call i32 @_Z7DEFAULTv()
-// CHECK:  call void @_ZN10TCPPObjectC1ERKS_i(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* [[THREE]], i32 [[CALL]])
+// CHECK:  call void @_ZN10TCPPObjectC1ERKS_i(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* nonnull [[THREE]], i32 [[CALL]])
 // CHECK:  ret void
 
 // CHECK: define internal void @"\01-[MyDocument MyProperty]"(
@@ -46,7 +46,7 @@
 // CHECK-LABEL: define internal void @__assign_helper_atomic_property_(
 // CHECK: [[TWO:%.*]] = load %struct.TCPPObject** [[ADDR:%.*]], align 8
 // CHECK: [[THREE:%.*]] = load %struct.TCPPObject** [[ADDR1:%.*]], align 8
-// CHECK: [[CALL:%.*]] = call %struct.TCPPObject* @_ZN10TCPPObjectaSERKS_(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* [[THREE]])
+// CHECK: [[CALL:%.*]] = call nonnull %struct.TCPPObject* @_ZN10TCPPObjectaSERKS_(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* nonnull [[THREE]])
 // CHECK:  ret void
 
 // CHECK: define internal void @"\01-[MyDocument setMyProperty:]"(
diff --git a/test/CodeGenObjCXX/property-objects.mm b/test/CodeGenObjCXX/property-objects.mm
index 88e992c..732d10f 100644
--- a/test/CodeGenObjCXX/property-objects.mm
+++ b/test/CodeGenObjCXX/property-objects.mm
@@ -32,7 +32,7 @@
 @synthesize frame;
 
 // CHECK: define internal void @"\01-[I setPosition:]"
-// CHECK: call %class.S* @_ZN1SaSERKS_
+// CHECK: call nonnull %class.S* @_ZN1SaSERKS_
 // CHECK-NEXT: ret void
 
 - (void)setFrame:(CGRect)frameRect {}
@@ -55,7 +55,7 @@
 @end
 
 // CHECK-LABEL: define i32 @main
-// CHECK: call void @_ZN1SC1ERKS_(%class.S* [[AGGTMP:%[a-zA-Z0-9\.]+]], %class.S* {{%[a-zA-Z0-9\.]+}})
+// CHECK: call void @_ZN1SC1ERKS_(%class.S* [[AGGTMP:%[a-zA-Z0-9\.]+]], %class.S* nonnull {{%[a-zA-Z0-9\.]+}})
 // CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %class.S*)*)(i8* {{%[a-zA-Z0-9\.]+}}, i8* {{%[a-zA-Z0-9\.]+}}, %class.S* [[AGGTMP]])
 // CHECK-NEXT: ret i32 0
 int main() {
@@ -68,7 +68,7 @@
 // rdar://8379892
 // CHECK-LABEL: define void @_Z1fP1A
 // CHECK: call void @_ZN1XC1Ev(%struct.X* [[LVTEMP:%[a-zA-Z0-9\.]+]])
-// CHECK: call void @_ZN1XC1ERKS_(%struct.X* [[AGGTMP:%[a-zA-Z0-9\.]+]], %struct.X* [[LVTEMP]])
+// CHECK: call void @_ZN1XC1ERKS_(%struct.X* [[AGGTMP:%[a-zA-Z0-9\.]+]], %struct.X* nonnull [[LVTEMP]])
 // CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.X*)*)({{.*}} %struct.X* [[AGGTMP]])
 struct X {
   X();
diff --git a/test/CodeGenObjCXX/property-reference.mm b/test/CodeGenObjCXX/property-reference.mm
index a4af900..8ac59ac 100644
--- a/test/CodeGenObjCXX/property-reference.mm
+++ b/test/CodeGenObjCXX/property-reference.mm
@@ -26,7 +26,7 @@
   const MyStruct& currentMyStruct = myClass.foo;   
 }
 
-// CHECK: [[C:%.*]] = call %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: [[C:%.*]] = call nonnull %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
 // CHECK:   store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]]
 
 namespace test1 {
@@ -40,7 +40,7 @@
 @implementation Test1
 @synthesize prop1 = ivar;
 @end
-// CHECK:    define internal [[A:%.*]]* @"\01-[Test1 prop1]"(
+// CHECK:    define internal nonnull [[A:%.*]]* @"\01-[Test1 prop1]"(
 // CHECK:      [[SELF:%.*]] = alloca [[TEST1:%.*]]*, align 8
 // CHECK:      [[T0:%.*]] = load [[TEST1]]** [[SELF]]
 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
@@ -49,7 +49,7 @@
 // CHECK-NEXT: ret [[A]]* [[T3]]
 
 // CHECK:    define internal void @"\01-[Test1 setProp1:]"(
-// CHECK:      call [[A]]* @_ZN5test11AaSERKS0_(
+// CHECK:      call nonnull [[A]]* @_ZN5test11AaSERKS0_(
 // CHECK-NEXT: ret void
 
 // rdar://problem/10497174
diff --git a/test/CodeGenOpenCL/builtins-r600.cl b/test/CodeGenOpenCL/builtins-r600.cl
new file mode 100644
index 0000000..0531038
--- /dev/null
+++ b/test/CodeGenOpenCL/builtins-r600.cl
@@ -0,0 +1,30 @@
+// REQUIRES: r600-registered-target
+// RUN: %clang_cc1 -triple r600-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// CHECK-LABEL: @test_div_scale_f64
+// CHECK: call { double, i1 } @llvm.AMDGPU.div.scale.f64(double %a, double %b, i1 true)
+// CHECK-DAG: [[FLAG:%.+]] = extractvalue { double, i1 } %{{.+}}, 1
+// CHECK-DAG: [[VAL:%.+]] = extractvalue { double, i1 } %{{.+}}, 0
+// CHECK: [[FLAGEXT:%.+]] = zext i1 [[FLAG]] to i32
+// CHECK: store i32 [[FLAGEXT]]
+void test_div_scale_f64(global double* out, global int* flagout, double a, double b)
+{
+  bool flag;
+  *out = __builtin_amdgpu_div_scale(a, b, true, &flag);
+  *flagout = flag;
+}
+
+// CHECK-LABEL: @test_div_scale_f32
+// CHECK: call { float, i1 } @llvm.AMDGPU.div.scale.f32(float %a, float %b, i1 true)
+// CHECK-DAG: [[FLAG:%.+]] = extractvalue { float, i1 } %{{.+}}, 1
+// CHECK-DAG: [[VAL:%.+]] = extractvalue { float, i1 } %{{.+}}, 0
+// CHECK: [[FLAGEXT:%.+]] = zext i1 [[FLAG]] to i32
+// CHECK: store i32 [[FLAGEXT]]
+void test_div_scale_f32(global float* out, global int* flagout, float a, float b)
+{
+  bool flag;
+  *out = __builtin_amdgpu_div_scalef(a, b, true, &flag);
+  *flagout = flag;
+}
diff --git a/test/CodeGenOpenCL/local.cl b/test/CodeGenOpenCL/local.cl
index 309c31a..895c8fa 100644
--- a/test/CodeGenOpenCL/local.cl
+++ b/test/CodeGenOpenCL/local.cl
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 __kernel void foo(void) {
-  // CHECK: @foo.i = internal addrspace(2)
+  // CHECK: @foo.i = internal unnamed_addr addrspace(2)
   __local int i;
   ++i;
 }
diff --git a/test/CodeGenOpenCL/str_literals.cl b/test/CodeGenOpenCL/str_literals.cl
index 78a9305..43c90f8 100644
--- a/test/CodeGenOpenCL/str_literals.cl
+++ b/test/CodeGenOpenCL/str_literals.cl
@@ -3,7 +3,7 @@
 __constant char * __constant x = "hello world";
 __constant char * __constant y = "hello world";
 
-// CHECK: addrspace(3) unnamed_addr constant
+// CHECK: unnamed_addr addrspace(3) constant
 // CHECK-NOT: addrspace(3) unnamed_addr constant
 // CHECK: @x = addrspace(3) global i8 addrspace(3)*
 // CHECK: @y = addrspace(3) global i8 addrspace(3)*
diff --git a/test/Coverage/c-language-features.inc b/test/Coverage/c-language-features.inc
index 0ff1237..3566879 100644
--- a/test/Coverage/c-language-features.inc
+++ b/test/Coverage/c-language-features.inc
@@ -196,3 +196,15 @@
   } f0;
   int f1;
 };
+
+// Unnamed structures.
+struct s12 {
+  struct {
+    unsigned char aa;
+    unsigned char bb;
+  };
+};
+
+void f11() {
+  struct s12 var = { .aa = 33 };
+}
diff --git a/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
diff --git a/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
diff --git a/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
diff --git a/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
diff --git a/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
diff --git a/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
diff --git a/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd b/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
diff --git a/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold b/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
diff --git a/test/Driver/Inputs/cl-libs/cl-test.lib b/test/Driver/Inputs/cl-libs/cl-test.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/cl-libs/cl-test.lib
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/lib/mips64-linux-gnuabi64/.keep b/test/Driver/Inputs/debian_6_mips64_tree/lib/mips64-linux-gnuabi64/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/lib/mips64-linux-gnuabi64/.keep
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/lib/mips64el-linux-gnuabi64/.keep b/test/Driver/Inputs/debian_6_mips64_tree/lib/mips64el-linux-gnuabi64/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/lib/mips64el-linux-gnuabi64/.keep
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/backward/.keep b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/backward/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/backward/.keep
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64-linux-gnuabi64/.keep b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64-linux-gnuabi64/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64-linux-gnuabi64/.keep
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64el-linux-gnuabi64/.keep b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64el-linux-gnuabi64/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64el-linux-gnuabi64/.keep
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64-linux-gnuabi64/.keep b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64-linux-gnuabi64/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64-linux-gnuabi64/.keep
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64el-linux-gnuabi64/.keep b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64el-linux-gnuabi64/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64el-linux-gnuabi64/.keep
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtbegin.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtbegin.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtend.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtend.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtbegin.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtbegin.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtend.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtend.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crt1.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crt1.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crti.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crti.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crtn.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crtn.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crt1.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crt1.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crti.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crti.o
diff --git a/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crtn.o b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crtn.o
diff --git a/test/Driver/Inputs/mips_img_tree/bin/.keep b/test/Driver/Inputs/mips_img_tree/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/bin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtbegin.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtbegin.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtend.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtend.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtbegin.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtend.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtend.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/el/.keep b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/el/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/el/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/64/el/.keep b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/64/el/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/64/el/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/el/.keep b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/el/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/el/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include/.keep b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtbegin.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtbegin.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtend.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtend.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtbegin.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtend.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtend.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtbegin.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtbegin.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtend.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtend.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtbegin.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtbegin.o
diff --git a/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtend.o b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtend.o
diff --git a/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/bin/.keep b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/bin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/include/c++/4.9.0/.keep b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/include/c++/4.9.0/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/include/c++/4.9.0/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/el/.keep b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/el/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/el/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/64/el/.keep b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/64/el/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/64/el/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/el/.keep b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/el/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/el/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/bin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/bin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crti.o b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/sbin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/sbin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/sbin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/bin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/bin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crti.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/sbin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/sbin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/sbin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/bin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/bin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crt1.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crti.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crtn.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/sbin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/sbin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/sbin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/bin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/bin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crt1.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crti.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crtn.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/sbin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/sbin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/sbin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/bin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/bin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crt1.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crti.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crtn.o b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/sbin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/sbin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/sbin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/usr/bin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/usr/bin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/usr/bin/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/usr/include/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/usr/include/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/usr/include/.keep
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crt1.o b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crti.o b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crti.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crtn.o b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crtn.o
diff --git a/test/Driver/Inputs/mips_img_tree/sysroot/usr/sbin/.keep b/test/Driver/Inputs/mips_img_tree/sysroot/usr/sbin/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/mips_img_tree/sysroot/usr/sbin/.keep
diff --git a/test/Driver/Inputs/module/module.modulemap b/test/Driver/Inputs/module/module.modulemap
new file mode 100644
index 0000000..4fddd4b
--- /dev/null
+++ b/test/Driver/Inputs/module/module.modulemap
@@ -0,0 +1,4 @@
+module simple {
+  header "simple.h"
+  export *
+}
diff --git a/test/Driver/Inputs/module/simple.h b/test/Driver/Inputs/module/simple.h
new file mode 100644
index 0000000..afd674e
--- /dev/null
+++ b/test/Driver/Inputs/module/simple.h
@@ -0,0 +1 @@
+#define MODULE_MACRO 10
diff --git a/test/Driver/Inputs/multilib_64bit_linux_tree/libx32/.keep b/test/Driver/Inputs/multilib_64bit_linux_tree/libx32/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/multilib_64bit_linux_tree/libx32/.keep
diff --git a/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32/crtbegin.o b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32/crtbegin.o
diff --git a/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/32/crtbegin.o b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/32/crtbegin.o
diff --git a/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/crtbegin.o b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/crtbegin.o
diff --git a/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/x32/crtbegin.o b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/x32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/x32/crtbegin.o
diff --git a/test/Driver/Inputs/multilib_64bit_linux_tree/usr/x86_64-unknown-linux/libx32/.keep b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/x86_64-unknown-linux/libx32/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/x86_64-unknown-linux/libx32/.keep
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/powerpc64le-linux-gnu/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/powerpc64le-linux-gnu/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/powerpc64le-linux-gnu/.keep
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/libx32/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/libx32/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/libx32/.keep
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/powerpc64le-linux-gnu/c++/4.8/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/powerpc64le-linux-gnu/c++/4.8/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/powerpc64le-linux-gnu/c++/4.8/.keep
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/x32/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/x32/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/x32/.keep
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtbegin.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtbegin.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtend.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtend.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.9/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.9/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.9/.keep
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtbegin.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtbegin.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crt1.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crt1.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crti.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crti.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crtn.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crtn.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/x86_64-linux-gnu/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/x86_64-linux-gnu/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/x86_64-linux-gnu/.keep
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crt1.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crt1.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crti.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crti.o
diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crtn.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crtn.o
diff --git a/test/Driver/altivec-asm.S b/test/Driver/altivec-asm.S
index 4143d52..3f78b58 100644
--- a/test/Driver/altivec-asm.S
+++ b/test/Driver/altivec-asm.S
@@ -1,3 +1,4 @@
 // RUN: %clang -target powerpc64-linux-gnu -maltivec -S %s -o - | FileCheck %s
+// RUN: %clang -target powerpc64le-linux-gnu -maltivec -S %s -o - | FileCheck %s
 // Verify that assembling an empty file does not auto-include altivec.h.
 // CHECK-NOT: static vector
diff --git a/test/Driver/arm-long-calls.c b/test/Driver/arm-long-calls.c
new file mode 100644
index 0000000..62294a0
--- /dev/null
+++ b/test/Driver/arm-long-calls.c
@@ -0,0 +1,15 @@
+// RUN: %clang -target armv7-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-DEFAULT
+
+// RUN: %clang -target armv7-eabi -### -mlong-calls %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-LONG-CALLS
+
+// RUN: %clang -target armv7-eabi -### -mlong-calls -mno-long-calls %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-LONG-CALLS
+
+// CHECK-DEFAULT-NOT: "-backend-option" "-arm-long-calls"
+
+// CHECK-LONG-CALLS: "-backend-option" "-arm-long-calls"
+
+// CHECK-NO-LONG-CALLS-NOT: "-backend-option" "-arm-long-calls"
+
diff --git a/test/Driver/cl-eh.cpp b/test/Driver/cl-eh.cpp
new file mode 100644
index 0000000..8a3450a
--- /dev/null
+++ b/test/Driver/cl-eh.cpp
@@ -0,0 +1,24 @@
+// Don't attempt slash switches on msys bash.
+// REQUIRES: shell-preserves-root
+
+// Note: %s must be preceded by --, otherwise it may be interpreted as a
+// command-line option, e.g. on Mac where %s is commonly under /Users.
+
+// RUN: %clang_cl /c /EHsc -### -- %s 2>&1 | FileCheck -check-prefix=EHsc %s
+// EHsc: "-fexceptions"
+
+// RUN: %clang_cl /c /EHs-c- -### -- %s 2>&1 | FileCheck -check-prefix=EHs_c_ %s
+// EHs_c_-NOT: "-fexceptions"
+
+// RUN: %clang_cl /c /EHs- /EHc- -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHc_ %s
+// EHs_EHc_-NOT: "-fexceptions"
+
+// RUN: %clang_cl /c /EHs- /EHs -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHs %s
+// EHs_EHs: "-fexceptions"
+
+// RUN: %clang_cl /c /EHs- /EHsa -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHa %s
+// EHs_EHa: "-fexceptions"
+
+// RUN: %clang_cl /c /EHinvalid -### -- %s 2>&1 | FileCheck -check-prefix=EHinvalid %s
+// EHinvalid: error: invalid value 'invalid' in '/EH'
+// EHinvalid-NOT: error:
diff --git a/test/Driver/cl-fallback.c b/test/Driver/cl-fallback.c
index 1bb0993..bbc9ad8 100644
--- a/test/Driver/cl-fallback.c
+++ b/test/Driver/cl-fallback.c
@@ -5,7 +5,7 @@
 // command-line option, e.g. on Mac where %s is commonly under /Users.
 
 // RUN: %clang_cl /fallback /Dfoo=bar /Ubaz /Ifoo /O0 /Ox /GR /GR- /Gy /Gy- \
-// RUN:   /Gw /Gw- /LD /LDd /MD /MDd /MTd /MT /FImyheader.h /Zi \
+// RUN:   /Gw /Gw- /LD /LDd /EHs /EHs- /MD /MDd /MTd /MT /FImyheader.h /Zi \
 // RUN:   -### -- %s 2>&1 \
 // RUN:   | FileCheck %s
 // CHECK: "-fdiagnostics-format" "msvc-fallback"
@@ -25,10 +25,16 @@
 // CHECK: "/FImyheader.h"
 // CHECK: "/LD"
 // CHECK: "/LDd"
+// CHECK: "/EHs"
+// CHECK: "/EHs-"
 // CHECK: "/MT"
 // CHECK: "/Tc" "{{.*cl-fallback.c}}"
 // CHECK: "/Fo{{.*cl-fallback.*.obj}}"
 
+// RUN: %clang_cl /fallback /GR- -### -- %s 2>&1 | FileCheck -check-prefix=GR %s
+// GR: cl.exe
+// GR: "/GR-"
+
 // RUN: %clang_cl /fallback /Od -### -- %s 2>&1 | FileCheck -check-prefix=O0 %s
 // O0: cl.exe
 // O0: "/Od"
@@ -54,15 +60,12 @@
 // RUN:     FileCheck -check-prefix=ErrWarn %s
 // ErrWarn: warning: falling back to {{.*}}cl.exe
 
-// Don't attempt to run clang -cc1 with /fallback and /GR.  It isn't ready yet.
-// RUN: %clang_cl /fallback /c /GR -### -- %s 2>&1 | \
-// RUN:     FileCheck -check-prefix=RTTI %s
-// RTTI: warning: cannot compile RTTI yet, falling back to {{.*}}cl.exe
 // RUN: %clang_cl /fallback /c /GR /GR- -### -- %s 2>&1 | \
 // RUN:     FileCheck -check-prefix=NO_RTTI %s
 // NO_RTTI: "-cc1"
 // NO_RTTI: ||
 // NO_RTTI: cl.exe
+// NO_RTTI: "/GR-"
 
 // Don't fall back on non-C or C++ files.
 // RUN: %clang_cl /fallback -### -- %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=LL %s
diff --git a/test/Driver/cl-inputs.c b/test/Driver/cl-inputs.c
index 066e0e3..029aead 100644
--- a/test/Driver/cl-inputs.c
+++ b/test/Driver/cl-inputs.c
@@ -40,4 +40,13 @@
 // RUN: %clang_cl -### /Tc - 2>&1 | FileCheck -check-prefix=STDINTc %s
 // STDINTc: "-x" "c"
 
+// RUN: env LIB=%S/Inputs/cl-libs %clang_cl -### -- %s cl-test.lib 2>&1 | FileCheck -check-prefix=LIBINPUT %s
+// LIBINPUT: link.exe"
+// LIBINPUT: "cl-test.lib"
+
+// RUN: env LIB=%S/Inputs/cl-libs %clang_cl -### -- %s cl-test2.lib 2>&1 | FileCheck -check-prefix=LIBINPUT2 %s
+// LIBINPUT2: error: no such file or directory: 'cl-test2.lib'
+// LIBINPUT2: link.exe"
+// LIBINPUT2-NOT: "cl-test2.lib"
+
 void f();
diff --git a/test/Driver/cl-options.c b/test/Driver/cl-options.c
index 48f1a9e..90b6325 100644
--- a/test/Driver/cl-options.c
+++ b/test/Driver/cl-options.c
@@ -7,8 +7,15 @@
 
 // Alias options:
 
-// RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=C %s
-// C: -c
+// RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=c %s
+// c: -c
+
+// RUN: %clang_cl /C -### -- %s 2>&1 | FileCheck -check-prefix=C %s
+// C: error: invalid argument '-C' only allowed with '/E, /P or /EP'
+
+// RUN: %clang_cl /C /P -### -- %s 2>&1 | FileCheck -check-prefix=C_P %s
+// C_P: "-E"
+// C_P: "-C"
 
 // RUN: %clang_cl /Dfoo=bar -### -- %s 2>&1 | FileCheck -check-prefix=D %s
 // RUN: %clang_cl /D foo=bar -### -- %s 2>&1 | FileCheck -check-prefix=D %s
@@ -18,6 +25,11 @@
 // E: "-E"
 // E: "-o" "-"
 
+// RUN: %clang_cl /EP -### -- %s 2>&1 | FileCheck -check-prefix=EP %s
+// EP: "-E"
+// EP: "-P"
+// EP: "-o" "-"
+
 // RTTI is on by default; just check that we don't error.
 // RUN: %clang_cl /Zs /GR -- %s 2>&1
 
@@ -166,6 +178,8 @@
 // RUN:    /wd1234 \
 // RUN:    /Zc:forScope \
 // RUN:    /Zc:wchar_t \
+// RUN:    /Zc:inline \
+// RUN:    /Zc:rvalueCast \
 // RUN:    -### -- %s 2>&1 | FileCheck -check-prefix=IGNORED %s
 // IGNORED-NOT: argument unused during compilation
 
@@ -189,7 +203,6 @@
 // RUN:     /docname \
 // RUN:     /d2Zi+ \
 // RUN:     /EHsc \
-// RUN:     /EP \
 // RUN:     /F \
 // RUN:     /FA \
 // RUN:     /FAc \
@@ -276,10 +289,12 @@
 // RUN: %clang_cl /Zs /WX -m32 -m64 -### -- 2>&1 %s | FileCheck -check-prefix=MFLAGS %s
 // MFLAGS-NOT: argument unused during compilation
 
-// Use -fno-rtti by default.
-// RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=NoRTTI %s
-// NoRTTI: "-fno-rtti"
+// RTTI is on by default. /GR- controls -fno-rtti-data.
+// RUN: %clang_cl /c /GR- -### -- %s 2>&1 | FileCheck -check-prefix=NoRTTI %s
+// NoRTTI: "-fno-rtti-data"
+// NoRTTI-NOT: "-fno-rtti"
 // RUN: %clang_cl /c /GR -### -- %s 2>&1 | FileCheck -check-prefix=RTTI %s
+// RTTI-NOT: "-fno-rtti-data"
 // RTTI-NOT: "-fno-rtti"
 
 
diff --git a/test/Driver/cl-outputs.c b/test/Driver/cl-outputs.c
index ad4051d..46502f6 100644
--- a/test/Driver/cl-outputs.c
+++ b/test/Driver/cl-outputs.c
@@ -109,3 +109,11 @@
 // RUN: %clang_cl /P -### -- %s 2>&1 | FileCheck -check-prefix=P %s
 // P: "-E"
 // P: "-o" "cl-outputs.i"
+
+// RUN: %clang_cl /P /Fifoo -### -- %s 2>&1 | FileCheck -check-prefix=Fi1 %s
+// Fi1: "-E"
+// Fi1: "-o" "foo.i"
+
+// RUN: %clang_cl /P /Fifoo.x -### -- %s 2>&1 | FileCheck -check-prefix=Fi2 %s
+// Fi2: "-E"
+// Fi2: "-o" "foo.x"
diff --git a/test/Driver/clang-g-opts.c b/test/Driver/clang-g-opts.c
index 9ca1fd3..a9566b7 100644
--- a/test/Driver/clang-g-opts.c
+++ b/test/Driver/clang-g-opts.c
@@ -2,15 +2,23 @@
 // RUN: %clang -### -S %s -g -target x86_64-linux-gnu 2>&1 \
 // RUN:             | FileCheck --check-prefix=CHECK-WITH-G %s
 // RUN: %clang -### -S %s -g -target x86_64-apple-darwin 2>&1 \
-// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DARWIN %s
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
+// RUN: %clang -### -S %s -g -target i686-pc-openbsd 2>&1 \
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
+// RUN: %clang -### -S %s -g -target x86_64-pc-freebsd10.0 2>&1 \
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
 // RUN: %clang -### -S %s -g0    2>&1 | FileCheck --check-prefix=CHECK-WITHOUT-G %s
 // RUN: %clang -### -S %s -g -g0 2>&1 | FileCheck --check-prefix=CHECK-WITHOUT-G %s
 // RUN: %clang -### -S %s -g0 -g -target x86_64-linux-gnu 2>&1 \
 // RUN:             | FileCheck --check-prefix=CHECK-WITH-G %s
 // RUN: %clang -### -S %s -g0 -g -target x86_64-apple-darwin 2>&1 \
-// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DARWIN %s
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
+// RUN: %clang -### -S %s -g0 -g -target i686-pc-openbsd 2>&1 \
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
+// RUN: %clang -### -S %s -g0 -g -target x86_64-pc-freebsd10.0 2>&1 \
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
 
 // CHECK-WITHOUT-G-NOT: "-g"
 // CHECK-WITH-G: "-g"
-// CHECK-WITH-G-DARWIN: "-gdwarf-2"
+// CHECK-WITH-G-DWARF2: "-gdwarf-2"
 
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
index 54e5bbe..9db23a0 100644
--- a/test/Driver/clang-translation.c
+++ b/test/Driver/clang-translation.c
@@ -71,6 +71,12 @@
 // PPCPWR7: "-target-cpu" "pwr7"
 
 // RUN: %clang -target powerpc64-unknown-linux-gnu \
+// RUN: -### -S %s -mcpu=power8 2>&1 | FileCheck -check-prefix=PPCPWR8 %s
+// PPCPWR8: clang
+// PPCPWR8: "-cc1"
+// PPCPWR8: "-target-cpu" "pwr8"
+
+// RUN: %clang -target powerpc64-unknown-linux-gnu \
 // RUN: -### -S %s -mcpu=a2q 2>&1 | FileCheck -check-prefix=PPCA2Q %s
 // PPCA2Q: clang
 // PPCA2Q: "-cc1"
@@ -211,14 +217,15 @@
 // RUN:   | FileCheck --check-prefix=ANDROID-X86 %s
 // ANDROID-X86: clang
 // ANDROID-X86: "-target-cpu" "i686"
-// ANDROID-X86: "-target-feature" "+sse3"
+// ANDROID-X86: "-target-feature" "+ssse3"
 
 // RUN: %clang -target x86_64-linux-android -### -S %s 2>&1 \
 // RUN:        --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=ANDROID-X86_64 %s
 // ANDROID-X86_64: clang
 // ANDROID-X86_64: "-target-cpu" "x86-64"
-// ANDROID-X86_64: "-target-feature" "+sse3"
+// ANDROID-X86_64: "-target-feature" "+sse4.2"
+// ANDROID-X86_64: "-target-feature" "+popcnt"
 
 // RUN: %clang -target mips-linux-gnu -### -S %s 2>&1 | \
 // RUN: FileCheck -check-prefix=MIPS %s
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index c88ced0..c5ebe6c 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -129,6 +129,9 @@
 // RUN: %clang -S -O20 -o /dev/null %s 2>&1 | FileCheck -check-prefix=CHECK-INVALID-O %s
 // CHECK-INVALID-O: warning: optimization level '-O20' is unsupported; using '-O3' instead
 
+// RUN: %clang -### -S -finput-charset=iso-8859-1 -o /dev/null %s 2>&1 | FileCheck -check-prefix=CHECK-INVALID-CHARSET %s
+// CHECK-INVALID-CHARSET: error: invalid value 'iso-8859-1' in '-finput-charset=iso-8859-1'
+
 // Test that we don't error on these.
 // RUN: %clang -### -S -Werror                                                \
 // RUN:     -falign-functions -falign-functions=2 -fno-align-functions        \
@@ -140,9 +143,11 @@
 // RUN:     -fgcse -fno-gcse                                                  \
 // RUN:     -fident -fno-ident                                                \
 // RUN:     -fimplicit-templates -fno-implicit-templates                      \
+// RUN:     -finput-charset=UTF-8                                             \
 // RUN:     -fivopts -fno-ivopts                                              \
 // RUN:     -fnon-call-exceptions -fno-non-call-exceptions                    \
 // RUN:     -fpermissive -fno-permissive                                      \
+// RUN:     -fdefer-pop -fno-defer-pop                                        \
 // RUN:     -fprefetch-loop-arrays -fno-prefetch-loop-arrays                  \
 // RUN:     -fprofile-correction -fno-profile-correction                      \
 // RUN:     -fprofile-dir=bar                                                 \
diff --git a/test/Driver/crash-report-modules.m b/test/Driver/crash-report-modules.m
new file mode 100644
index 0000000..d1c7832
--- /dev/null
+++ b/test/Driver/crash-report-modules.m
@@ -0,0 +1,32 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only %s -I %S/Inputs/module                     \
+// RUN: -fmodules -fmodules-cache-path=/tmp/ -DFOO=BAR 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-report-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-report-*.sh
+// REQUIRES: crash-recovery
+
+// because of the glob (*.m, *.sh)
+// REQUIRES: shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+@import simple;
+const int x = MODULE_MACRO;
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import simple;
+// CHECKSRC: const int x = 10;
+
+// CHECKSH: -cc1
+// CHECKSH: -D "FOO=BAR"
+// CHECKSH-NOT: -fmodules-cache-path=/tmp/
+// CHECKSH: crash-report-modules-{{[^ ]*}}.m
+// CHECKSH: -ivfsoverlay crash-report-modules-{{[^ ]*}}.cache/vfs/vfs.yaml
diff --git a/test/Driver/crash-report.c b/test/Driver/crash-report.c
index 59ce8f7..da1ff95 100644
--- a/test/Driver/crash-report.c
+++ b/test/Driver/crash-report.c
@@ -3,7 +3,6 @@
 // RUN: not env TMPDIR=%t TEMP=%t TMP=%t RC_DEBUG_OPTIONS=1 %clang -fsyntax-only %s \
 // RUN:  -F/tmp/ -I /tmp/ -idirafter /tmp/ -iquote /tmp/ -isystem /tmp/ \
 // RUN:  -iprefix /the/prefix -iwithprefix /tmp -iwithprefixbefore /tmp/ \
-// RUN:  -fmodules -fcxx-modules -fmodules-cache-path=/tmp/              \
 // RUN:  -Xclang -internal-isystem -Xclang /tmp/                         \
 // RUN:  -Xclang -internal-externc-isystem -Xclang /tmp/                 \
 // RUN:  -DFOO=BAR 2>&1 | FileCheck %s
@@ -34,7 +33,7 @@
 // CHECKSH-NOT: -iprefix /the/prefix
 // CHECKSH-NOT: -iwithprefix /tmp/
 // CHECKSH-NOT: -iwithprefixbefore /tmp/
-// CHECKSH-NOT: -fmodules-cache-path=/tmp/
 // CHECKSH-NOT: -internal-isystem /tmp/
 // CHECKSH-NOT: -internal-externc-isystem /tmp/
 // CHECKSH-NOT: -dwarf-debug-flags
+// CHECKSH: crash-report-{{[^ ]*}}.c
diff --git a/test/Driver/cross-linux.c b/test/Driver/cross-linux.c
index 3013d80..ade8d8f 100644
--- a/test/Driver/cross-linux.c
+++ b/test/Driver/cross-linux.c
@@ -16,6 +16,14 @@
 //
 // RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
 // RUN:   --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \
+// RUN:   --target=x86_64-unknown-linux-gnux32 \
+// RUN:   | FileCheck --check-prefix=CHECK-X32 %s
+// CHECK-X32: "-cc1" "-triple" "x86_64-unknown-linux-gnux32"
+// CHECK-X32: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\}}as" "--x32"
+// CHECK-X32: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\}}ld" {{.*}} "-m" "elf32_x86_64"
+//
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN:   --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \
 // RUN:   --target=x86_64-unknown-linux-gnu -m32 \
 // RUN:   | FileCheck --check-prefix=CHECK-I386 %s
 //
diff --git a/test/Driver/debug-options.c b/test/Driver/debug-options.c
index 48f686b..e179ef0 100644
--- a/test/Driver/debug-options.c
+++ b/test/Driver/debug-options.c
@@ -38,11 +38,19 @@
 // RUN: %clang -### -c -gline-tables-only %s 2>&1 \
 // RUN:             | FileCheck -check-prefix=GLTO_ONLY %s
 // RUN: %clang -### -c -gline-tables-only %s -target x86_64-apple-darwin 2>&1 \
-// RUN:             | FileCheck -check-prefix=GLTO_ONLY_DARWIN %s
+// RUN:             | FileCheck -check-prefix=GLTO_ONLY_DWARF2 %s
+// RUN: %clang -### -c -gline-tables-only %s -target i686-pc-openbsd 2>&1 \
+// RUN:             | FileCheck -check-prefix=GLTO_ONLY_DWARF2 %s
+// RUN: %clang -### -c -gline-tables-only %s -target x86_64-pc-freebsd10.0 2>&1 \
+// RUN:             | FileCheck -check-prefix=GLTO_ONLY_DWARF2 %s
 // RUN: %clang -### -c -gline-tables-only -g %s -target x86_64-linux-gnu 2>&1 \
 // RUN:             | FileCheck -check-prefix=G_ONLY %s
 // RUN: %clang -### -c -gline-tables-only -g %s -target x86_64-apple-darwin 2>&1 \
-// RUN:             | FileCheck -check-prefix=G_ONLY_DARWIN %s
+// RUN:             | FileCheck -check-prefix=G_ONLY_DWARF2 %s
+// RUN: %clang -### -c -gline-tables-only -g %s -target i686-pc-openbsd 2>&1 \
+// RUN:             | FileCheck -check-prefix=G_ONLY_DWARF2 %s
+// RUN: %clang -### -c -gline-tables-only -g %s -target x86_64-pc-freebsd10.0 2>&1 \
+// RUN:             | FileCheck -check-prefix=G_ONLY_DWARF2 %s
 // RUN: %clang -### -c -gline-tables-only -g0 %s 2>&1 \
 // RUN:             | FileCheck -check-prefix=GLTO_NO %s
 //
@@ -78,21 +86,21 @@
 // GLTO_ONLY: "-gline-tables-only"
 // GLTO_ONLY-NOT: "-g"
 //
-// GLTO_ONLY_DARWIN: "-cc1"
-// GLTO_ONLY_DARWIN-NOT: "-g"
-// GLTO_ONLY_DARWIN: "-gline-tables-only"
-// GLTO_ONLY_DARWIN: "-gdwarf-2"
-// GLTO_ONLY_DARWIN-NOT: "-g"
+// GLTO_ONLY_DWARF2: "-cc1"
+// GLTO_ONLY_DWARF2-NOT: "-g"
+// GLTO_ONLY_DWARF2: "-gline-tables-only"
+// GLTO_ONLY_DWARF2: "-gdwarf-2"
+// GLTO_ONLY_DWARF2-NOT: "-g"
 //
 // G_ONLY: "-cc1"
 // G_ONLY-NOT: "-gline-tables-only"
 // G_ONLY: "-g"
 // G_ONLY-NOT: "-gline-tables-only"
 //
-// G_ONLY_DARWIN: "-cc1"
-// G_ONLY_DARWIN-NOT: "-gline-tables-only"
-// G_ONLY_DARWIN: "-gdwarf-2"
-// G_ONLY_DARWIN-NOT: "-gline-tables-only"
+// G_ONLY_DWARF2: "-cc1"
+// G_ONLY_DWARF2-NOT: "-gline-tables-only"
+// G_ONLY_DWARF2: "-gdwarf-2"
+// G_ONLY_DWARF2-NOT: "-gline-tables-only"
 //
 // GLTO_NO: "-cc1"
 // GLTO_NO-NOT: "-gline-tables-only"
diff --git a/test/Driver/dyld-prefix.c b/test/Driver/dyld-prefix.c
index 317d644..5336a11 100644
--- a/test/Driver/dyld-prefix.c
+++ b/test/Driver/dyld-prefix.c
@@ -7,3 +7,6 @@
 
 // RUN: %clang -target x86_64-unknown-linux --dyld-prefix /foo -### %t.o 2>&1 | FileCheck --check-prefix=CHECK-64 %s
 // CHECK-64: "-dynamic-linker" "/foo/lib64/ld-linux-x86-64.so.2"
+
+// RUN: %clang -target x86_64-unknown-linux-gnux32 --dyld-prefix /foo -### %t.o 2>&1 | FileCheck --check-prefix=CHECK-X32 %s
+// CHECK-X32: "-dynamic-linker" "/foo/libx32/ld-linux-x32.so.2"
diff --git a/test/Driver/freebsd-mips-as.c b/test/Driver/freebsd-mips-as.c
index 12b9876..da2d120 100644
--- a/test/Driver/freebsd-mips-as.c
+++ b/test/Driver/freebsd-mips-as.c
@@ -80,12 +80,12 @@
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-32R2 %s
 // MIPS-ALIAS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 //
-// RUN: %clang -target mips-unknown-freebsd -mips64 -### \
+// RUN: %clang -target mips64-unknown-freebsd -mips64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64 %s
 // MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
 //
-// RUN: %clang -target mips-unknown-freebsd -mips64r2 -### \
+// RUN: %clang -target mips64-unknown-freebsd -mips64r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R2 %s
 // MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB"
diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c
index 4b45d05..f0275d0 100644
--- a/test/Driver/freebsd.c
+++ b/test/Driver/freebsd.c
@@ -1,9 +1,8 @@
-// REQUIRES: powerpc-registered-target,mips-registered-target
 // RUN: %clang -no-canonical-prefixes \
 // RUN:   -target powerpc-pc-freebsd8 %s    \
 // RUN:   --sysroot=%S/Inputs/basic_freebsd_tree -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PPC %s
-// CHECK-PPC: clang{{.*}}" "-cc1" "-triple" "powerpc-pc-freebsd8"
+// CHECK-PPC: "-cc1" "-triple" "powerpc-pc-freebsd8"
 // CHECK-PPC: ld{{.*}}" "--sysroot=[[SYSROOT:[^"]+]]"
 // CHECK-PPC: "--eh-frame-hdr" "-dynamic-linker" "{{.*}}ld-elf{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "-L[[SYSROOT]]/usr/lib" "{{.*}}.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "{{.*}}crtend.o" "{{.*}}crtn.o"
 //
@@ -11,7 +10,7 @@
 // RUN:   -target powerpc64-pc-freebsd8 %s                              \
 // RUN:   --sysroot=%S/Inputs/basic_freebsd64_tree -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PPC64 %s
-// CHECK-PPC64: clang{{.*}}" "-cc1" "-triple" "powerpc64-pc-freebsd8"
+// CHECK-PPC64: "-cc1" "-triple" "powerpc64-pc-freebsd8"
 // CHECK-PPC64: ld{{.*}}" "--sysroot=[[SYSROOT:[^"]+]]"
 // CHECK-PPC64: "--eh-frame-hdr" "-dynamic-linker" "{{.*}}ld-elf{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "-L[[SYSROOT]]/usr/lib" "{{.*}}.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "{{.*}}crtend.o" "{{.*}}crtn.o"
 //
@@ -21,7 +20,7 @@
 // RUN: %clang -no-canonical-prefixes -target x86_64-pc-freebsd8 -m32 %s \
 // RUN:   --sysroot=%S/Inputs/multiarch_freebsd64_tree -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-LIB32 %s
-// CHECK-LIB32: clang{{.*}}" "-cc1" "-triple" "i386-pc-freebsd8"
+// CHECK-LIB32: "-cc1" "-triple" "i386-pc-freebsd8"
 // CHECK-LIB32: ld{{.*}}" {{.*}} "-m" "elf_i386_fbsd"
 //
 // RUN: %clang -target x86_64-pc-freebsd8 -m32 %s 2>&1 \
@@ -99,20 +98,20 @@
 
 // RUN: %clang %s -### -target arm-unknown-freebsd10.0 -no-integrated-as 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ARM %s
-// CHECK-ARM: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions"
+// CHECK-ARM: "-cc1"{{.*}}" "-fsjlj-exceptions"
 // CHECK-ARM: as{{.*}}" "-mfpu=softvfp"{{.*}}"-matpcs"
 // CHECK-ARM-EABI-NOT: as{{.*}}" "-mfpu=vfp"
 
 // RUN: %clang %s -### -target arm-gnueabi-freebsd10.0 -no-integrated-as 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ARM-EABI %s
-// CHECK-ARM-EABI-NOT: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions"
+// CHECK-ARM-EABI-NOT: "-cc1"{{.*}}" "-fsjlj-exceptions"
 // CHECK-ARM-EABI: as{{.*}}" "-mfpu=softvfp" "-meabi=5"
 // CHECK-ARM-EABI-NOT: as{{.*}}" "-mfpu=vfp"
 // CHECK-ARM-EABI-NOT: as{{.*}}" "-matpcs"
 
 // RUN: %clang %s -### -target arm-gnueabihf-freebsd10.0 -no-integrated-as 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ARM-EABIHF %s
-// CHECK-ARM-EABIHF-NOT: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions"
+// CHECK-ARM-EABIHF-NOT: "-cc1"{{.*}}" "-fsjlj-exceptions"
 // CHECK-ARM-EABIHF: as{{.*}}" "-mfpu=vfp" "-meabi=5"
 // CHECK-ARM-EABIHF-NOT: as{{.*}}" "-mfpu=softvfp"
 // CHECK-ARM-EABIHF-NOT: as{{.*}}" "-matpcs"
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 9c84086..57ea5a2 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -18,18 +18,6 @@
 // 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
 // CHECK-PARTIAL-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift|unreachable|return|vla-bound|alignment|null|object-size|array-bounds),?){12}"}}
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address-full %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FULL
-// CHECK-ASAN-FULL: "-fsanitize={{((address|init-order|use-after-return|use-after-scope),?){4}"}}
-
-// RUN: %clang -target x86_64-linux-gnu -fno-sanitize=init-order,use-after-return -fsanitize=address %s -### 2>&1 |  FileCheck %s --check-prefix=CHECK-ASAN-IMPLIED-INIT-ORDER-UAR
-// CHECK-ASAN-IMPLIED-INIT-ORDER-UAR: "-fsanitize={{((address|init-order|use-after-return),?){3}"}}
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize=init-order %s -### 2>&1 |  FileCheck %s --check-prefix=CHECK-ASAN-NO-IMPLIED-INIT-ORDER
-// CHECK-ASAN-NO-IMPLIED-INIT-ORDER-NOT: init-order
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize=use-after-return %s -### 2>&1 |  FileCheck %s --check-prefix=CHECK-ASAN-NO-IMPLIED-UAR
-// CHECK-ASAN-NO-IMPLIED-UAR-NOT: use-after-return
-
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP-ON-ERROR-UNDEF
 // CHECK-UNDEFINED-TRAP-ON-ERROR-UNDEF: '-fsanitize=undefined' not allowed with '-fsanitize-undefined-trap-on-error'
 
@@ -58,15 +46,6 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=leak,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-SANM
 // CHECK-SANL-SANM: '-fsanitize=leak' not allowed with '-fsanitize=memory'
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=init-order %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-EXTRA-ASAN
-// CHECK-ONLY-EXTRA-ASAN: '-fsanitize=init-order' is ignored in absence of '-fsanitize=address'
-
-// RUN: %clang -target x86_64-linux-gnu -Wno-unused-sanitize-argument -fsanitize=init-order %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-WNO-UNUSED-SANITIZE-ARGUMENT
-// CHECK-WNO-UNUSED-SANITIZE-ARGUMENT-NOT: '-fsanitize=init-order' is ignored in absence of '-fsanitize=address'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address,init-order -fno-sanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NOWARN-ONLY-EXTRA-ASAN
-// CHECK-NOWARN-ONLY-EXTRA-ASAN-NOT: is ignored in absence of '-fsanitize=address'
-
 // RUN: %clang -target x86_64-linux-gnu -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-TRACK-ORIGINS
 // CHECK-ONLY-TRACK-ORIGINS: warning: argument unused during compilation: '-fsanitize-memory-track-origins'
 
diff --git a/test/Driver/fuse-ld.c b/test/Driver/fuse-ld.c
new file mode 100644
index 0000000..bd25b8d
--- /dev/null
+++ b/test/Driver/fuse-ld.c
@@ -0,0 +1,63 @@
+// RUN: %clang %s -### \
+// RUN:     -target x86_64-unknown-freebsd 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-FREEBSD-LD
+// CHECK-FREEBSD-LD: ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-BFD
+// CHECK-FREEBSD-BFD: Inputs/basic_freebsd_tree/usr/bin{{/|\\+}}ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-GOLD
+// CHECK-FREEBSD-GOLD: Inputs/basic_freebsd_tree/usr/bin{{/|\\+}}ld.gold
+
+// RUN: %clang %s -### -fuse-ld=plib \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-PLIB
+// CHECK-FREEBSD-PLIB: error: invalid linker name
+
+
+
+// RUN: %clang %s -### \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD
+// CHECK-ANDROID-ARM-LD: Inputs/basic_android_tree/bin{{/|\\+}}arm-linux-androideabi-ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD
+// CHECK-ANDROID-ARM-BFD: Inputs/basic_android_tree/bin{{/|\\+}}arm-linux-androideabi-ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD
+// CHECK-ANDROID-ARM-GOLD: Inputs/basic_android_tree/bin{{/|\\+}}arm-linux-androideabi-ld.gold
+
+// RUN: %clang %s -### \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD-TC
+// CHECK-ANDROID-ARM-LD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD-TC
+// CHECK-ANDROID-ARM-BFD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD-TC
+// CHECK-ANDROID-ARM-GOLD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld.gold
diff --git a/test/Driver/hexagon-toolchain-elf.c b/test/Driver/hexagon-toolchain-elf.c
index f60c61c..87c33c7 100644
--- a/test/Driver/hexagon-toolchain-elf.c
+++ b/test/Driver/hexagon-toolchain-elf.c
@@ -1,5 +1,3 @@
-// REQUIRES: hexagon-registered-target
-
 // -----------------------------------------------------------------------------
 // Test standard include paths
 // -----------------------------------------------------------------------------
@@ -135,7 +133,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK011 %s
-// CHECK011: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK011: "-cc1"
 // CHECK011-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK011-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK011-NOT: "-static"
@@ -159,7 +157,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK012 %s
-// CHECK012: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK012: "-cc1"
 // CHECK012-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK012-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK012-NOT: "-static"
@@ -185,7 +183,7 @@
 // RUN:   -Lone -L two -L three \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK013 %s
-// CHECK013: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK013: "-cc1"
 // CHECK013-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK013-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK013: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -209,7 +207,7 @@
 // RUN:   -static \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK014 %s
-// CHECK014: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK014: "-cc1"
 // CHECK014-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK014-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK014: "-static"
@@ -230,7 +228,7 @@
 // RUN:   -shared \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK015 %s
-// CHECK015: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK015: "-cc1"
 // CHECK015-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK015-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK015: "-shared" "-call_shared"
@@ -260,7 +258,7 @@
 // RUN:   -static \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK016 %s
-// CHECK016: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK016: "-cc1"
 // CHECK016-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK016-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK016: "-shared" "-call_shared" "-static"
@@ -292,7 +290,7 @@
 // RUN:   -nostdlib \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK017 %s
-// CHECK017: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK017: "-cc1"
 // CHECK017-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK017-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK017-NOT: crt0_standalone.o
@@ -318,7 +316,7 @@
 // RUN:   -nostartfiles \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK018 %s
-// CHECK018: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK018: "-cc1"
 // CHECK018-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK018-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK018-NOT: crt0_standalone.o
@@ -344,7 +342,7 @@
 // RUN:   -nodefaultlibs \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK019 %s
-// CHECK019: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK019: "-cc1"
 // CHECK019-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK019-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK019: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -373,7 +371,7 @@
 // RUN:   -moslib=first -moslib=second \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK020 %s
-// CHECK020: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK020: "-cc1"
 // CHECK020-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK020-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK020-NOT: "-static"
@@ -398,7 +396,7 @@
 // RUN:   -moslib=first -moslib=second -moslib=standalone\
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK021 %s
-// CHECK021: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK021: "-cc1"
 // CHECK021-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK021-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK021-NOT: "-static"
@@ -430,7 +428,7 @@
 // RUN:   -uFoo -undefined Bar \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK022 %s
-// CHECK022: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK022: "-cc1"
 // CHECK022-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK022-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK022: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -457,7 +455,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK023 %s
-// CHECK023:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK023:      "-cc1"
 // CHECK023:        "-mrelocation-model" "static"
 // CHECK023-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK023-NOT:    "-G{{[0-9]+}}"
@@ -480,7 +478,7 @@
 // RUN:   -msmall-data-threshold=8 \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK024 %s
-// CHECK024:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK024:      "-cc1"
 // CHECK024-NOT:    "-mrelocation-model" "static"
 // CHECK024:        "-pic-level" "{{[12]}}"
 // CHECK024:        "-mllvm" "-hexagon-small-data-threshold=0"
@@ -504,7 +502,7 @@
 // RUN:   -msmall-data-threshold=8 \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK025 %s
-// CHECK025:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK025:      "-cc1"
 // CHECK025:        "-mrelocation-model" "static"
 // CHECK025:        "-mllvm" "-hexagon-small-data-threshold=8"
 // CHECK025-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
@@ -520,7 +518,7 @@
 // RUN:   -pie \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK026 %s
-// CHECK026:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK026:      "-cc1"
 // CHECK026-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK026-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK026:        "-pie"
@@ -530,7 +528,7 @@
 // RUN:   -pie -shared \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK027 %s
-// CHECK027:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK027:      "-cc1"
 // CHECK027-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK027-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK027-NOT:    "-pie"
@@ -542,7 +540,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK028 %s
-// CHECK028:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK028:      "-cc1"
 // CHECK028:        "-mqdsp6-compat"
 // CHECK028:        "-Wreturn-type"
 // CHECK028-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
@@ -558,7 +556,7 @@
 // RUN:   -Xassembler --keep-locals \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK029 %s
-// CHECK029:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK029:      "-cc1"
 // CHECK029-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK029:      "--noexecstack" "--trap" "--keep-locals"
 // CHECK029-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
diff --git a/test/Driver/hexagon-toolchain.c b/test/Driver/hexagon-toolchain.c
index f3d7e25..88440f8 100644
--- a/test/Driver/hexagon-toolchain.c
+++ b/test/Driver/hexagon-toolchain.c
@@ -1,5 +1,3 @@
-// REQUIRES: hexagon-registered-target
-
 // -----------------------------------------------------------------------------
 // Test standard include paths
 // -----------------------------------------------------------------------------
@@ -135,7 +133,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK011 %s
-// CHECK011: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK011: "-cc1"
 // CHECK011-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK011-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK011-NOT: "-static"
@@ -159,7 +157,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK012 %s
-// CHECK012: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK012: "-cc1"
 // CHECK012-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK012-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK012-NOT: "-static"
@@ -185,7 +183,7 @@
 // RUN:   -Lone -L two -L three \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK013 %s
-// CHECK013: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK013: "-cc1"
 // CHECK013-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK013-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK013: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -209,7 +207,7 @@
 // RUN:   -static \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK014 %s
-// CHECK014: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK014: "-cc1"
 // CHECK014-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK014-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK014: "-static"
@@ -230,7 +228,7 @@
 // RUN:   -shared \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK015 %s
-// CHECK015: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK015: "-cc1"
 // CHECK015-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK015-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK015: "-shared" "-call_shared"
@@ -260,7 +258,7 @@
 // RUN:   -static \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK016 %s
-// CHECK016: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK016: "-cc1"
 // CHECK016-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK016-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK016: "-shared" "-call_shared" "-static"
@@ -292,7 +290,7 @@
 // RUN:   -nostdlib \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK017 %s
-// CHECK017: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK017: "-cc1"
 // CHECK017-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK017-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK017-NOT: crt0_standalone.o
@@ -318,7 +316,7 @@
 // RUN:   -nostartfiles \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK018 %s
-// CHECK018: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK018: "-cc1"
 // CHECK018-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK018-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK018-NOT: crt0_standalone.o
@@ -344,7 +342,7 @@
 // RUN:   -nodefaultlibs \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK019 %s
-// CHECK019: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK019: "-cc1"
 // CHECK019-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK019-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK019: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -373,7 +371,7 @@
 // RUN:   -moslib=first -moslib=second \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK020 %s
-// CHECK020: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK020: "-cc1"
 // CHECK020-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK020-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK020-NOT: "-static"
@@ -398,7 +396,7 @@
 // RUN:   -moslib=first -moslib=second -moslib=standalone\
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK021 %s
-// CHECK021: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK021: "-cc1"
 // CHECK021-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK021-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK021-NOT: "-static"
@@ -430,7 +428,7 @@
 // RUN:   -uFoo -undefined Bar \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK022 %s
-// CHECK022: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK022: "-cc1"
 // CHECK022-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK022-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK022: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -457,7 +455,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK023 %s
-// CHECK023:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK023:      "-cc1"
 // CHECK023:        "-mrelocation-model" "static"
 // CHECK023-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK023-NOT:    "-G{{[0-9]+}}"
@@ -480,7 +478,7 @@
 // RUN:   -msmall-data-threshold=8 \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK024 %s
-// CHECK024:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK024:      "-cc1"
 // CHECK024-NOT:    "-mrelocation-model" "static"
 // CHECK024:        "-pic-level" "{{[12]}}"
 // CHECK024:        "-mllvm" "-hexagon-small-data-threshold=0"
@@ -504,7 +502,7 @@
 // RUN:   -msmall-data-threshold=8 \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK025 %s
-// CHECK025:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK025:      "-cc1"
 // CHECK025:        "-mrelocation-model" "static"
 // CHECK025:        "-mllvm" "-hexagon-small-data-threshold=8"
 // CHECK025-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
@@ -520,7 +518,7 @@
 // RUN:   -pie \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK026 %s
-// CHECK026:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK026:      "-cc1"
 // CHECK026-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK026-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK026:        "-pie"
@@ -530,7 +528,7 @@
 // RUN:   -pie -shared \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK027 %s
-// CHECK027:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK027:      "-cc1"
 // CHECK027-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK027-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK027-NOT:    "-pie"
@@ -542,7 +540,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK028 %s
-// CHECK028:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK028:      "-cc1"
 // CHECK028:        "-mqdsp6-compat"
 // CHECK028:        "-Wreturn-type"
 // CHECK028-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
@@ -558,7 +556,7 @@
 // RUN:   -Xassembler --keep-locals \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK029 %s
-// CHECK029:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK029:      "-cc1"
 // CHECK029-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK029:      "--noexecstack" "--trap" "--keep-locals"
 // CHECK029-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
diff --git a/test/Driver/ident_md.c b/test/Driver/ident_md.c
index d7da317..7b2b2f6 100644
--- a/test/Driver/ident_md.c
+++ b/test/Driver/ident_md.c
@@ -1,6 +1,6 @@
 // RUN: %clang %s -emit-llvm -S -o - | FileCheck %s
 // Verify that clang version appears in the llvm.ident metadata.
 
-// CHECK: !llvm.ident = !{!0}
-// CHECK: !0 = metadata !{metadata !{{.*}}
+// CHECK: !llvm.ident = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = metadata !{metadata !{{.*}}
 
diff --git a/test/Driver/linux-header-search.cpp b/test/Driver/linux-header-search.cpp
index b56a50a..9635519 100644
--- a/test/Driver/linux-header-search.cpp
+++ b/test/Driver/linux-header-search.cpp
@@ -55,6 +55,22 @@
 // CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnux32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04 %s
+// CHECK-UBUNTU-14-04: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-UBUNTU-14-04: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu/x32"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/x32"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|x32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu"
+// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+///
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
 // RUN:     -target arm-linux-gnueabihf \
 // RUN:     --sysroot=%S/Inputs/ubuntu_13.04_multiarch_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-13-04-CROSS %s
@@ -95,6 +111,22 @@
 // CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward"
 // CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/32"
 //
+// Test Ubuntu/Debian's Ubuntu 14.04 for powerpc64le
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target powerpc64le-unknown-linux-gnu -m32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04-PPC64LE %s
+// CHECK-UBUNTU-14-04-PPC64LE: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-UBUNTU-14-04-PPC64LE: "-triple" "powerpc64le-unknown-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8/powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8/backward"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/powerpc64le-linux-gnu/c++/4.8"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+//
 // Thoroughly exercise the Debian multiarch environment.
 // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
 // RUN:     -target i686-linux-gnu \
@@ -181,3 +213,35 @@
 // CHECK-GENTOO-4-6-4: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-GENTOO-4-6-4: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-GENTOO-4-6-4: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+//
+// Check header search on Debian 6 / MIPS64
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target mips64-unknown-linux-gnuabi64 \
+// RUN:     --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64-GNUABI %s
+// CHECK-MIPS64-GNUABI: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-MIPS64-GNUABI: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9/mips64-linux-gnuabi64"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9/backward"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/mips64-linux-gnuabi64"
+// CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+//
+// Check header search on Debian 6 / MIPS64
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target mips64el-unknown-linux-gnuabi64 \
+// RUN:     --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL-GNUABI %s
+// CHECK-MIPS64EL-GNUABI: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-MIPS64EL-GNUABI: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9/mips64el-linux-gnuabi64"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9/backward"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/mips64el-linux-gnuabi64"
+// CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index 5509e53..cbb4a71 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -34,6 +34,19 @@
 // CHECK-LD-64: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnux32 \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-X32 %s
+// CHECK-LD-X32-NOT: warning:
+// CHECK-LD-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-LD-X32: "--eh-frame-hdr"
+// CHECK-LD-X32: "-m" "elf32_x86_64"
+// CHECK-LD-X32: "-dynamic-linker"
+// CHECK-LD-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// CHECK-LD-X32: "-lc"
+// CHECK-LD-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=x86_64-unknown-linux \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:     --rtlib=compiler-rt \
@@ -186,6 +199,23 @@
 // CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnux32 \
+// RUN:     --sysroot=%S/Inputs/multilib_64bit_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-X32 %s
+// CHECK-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32{{/|\\\\}}crtbegin.o"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../libx32"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../libx32"
+// CHECK-X32: "-L[[SYSROOT]]/lib/../libx32"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/../libx32"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.."
+// CHECK-X32: "-L[[SYSROOT]]/lib"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=x86_64-unknown-linux -m32 \
 // RUN:     --gcc-toolchain=%S/Inputs/multilib_64bit_linux_tree/usr \
 // RUN:     --sysroot=%S/Inputs/multilib_32bit_linux_tree \
@@ -347,6 +377,43 @@
 // CHECK-X86-64-UBUNTU-13-10-ARM: "{{.*}}/usr/lib/gcc-cross/arm-linux-gnueabi/4.7{{/|\\\\}}crtend.o"
 // CHECK-X86-64-UBUNTU-13-10-ARM: "{{.*}}/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/../lib{{/|\\\\}}crtn.o"
 //
+// Check Ubuntu 14.04 on powerpc64le.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=powerpc64le-unknown-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04-PPC64LE %s
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crt1.o"
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crti.o"
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8{{/|\\\\}}crtbegin.o"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/lib/powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../.."
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8{{/|\\\\}}crtend.o"
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crtn.o"
+//
+// Check Ubuntu 14.04 on x32.
+// "/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32/crtn.o"
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnux32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04-X32 %s
+// CHECK-UBUNTU-14-04-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32{{/|\\\\}}crt1.o"
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32{{/|\\\\}}crti.o"
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/x32{{/|\\\\}}crtbegin.o"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/x32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/lib/../libx32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/../libx32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/x86_64-linux-gnu/../../libx32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.."
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/x32{{/|\\\\}}crtend.o"
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32{{/|\\\\}}crtn.o"
+//
 // Check fedora 18 on arm.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=armv7-unknown-linux-gnueabihf \
@@ -422,6 +489,13 @@
 // CHECK-ARM-HF: "-m" "armelf_linux_eabi"
 // CHECK-ARM-HF: "-dynamic-linker" "{{.*}}/lib/ld-linux-armhf.so.3"
 //
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     --target=powerpc64le-linux-gnu \
+// RUN:   | FileCheck --check-prefix=CHECK-PPC64LE %s
+// CHECK-PPC64LE: "{{.*}}ld{{(.exe)?}}"
+// CHECK-PPC64LE: "-m" "elf64lppc"
+// CHECK-PPC64LE: "-dynamic-linker" "{{.*}}/lib64/ld64.so.2"
+//
 // Check that we do not pass --hash-style=gnu and --hash-style=both to linker
 // and provide correct path to the dynamic linker and emulation mode when build
 // for MIPS platforms.
@@ -432,6 +506,7 @@
 // CHECK-MIPS: "-m" "elf32btsmip"
 // CHECK-MIPS: "-dynamic-linker" "{{.*}}/lib/ld.so.1"
 // CHECK-MIPS-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPSEL %s
@@ -439,6 +514,21 @@
 // CHECK-MIPSEL: "-m" "elf32ltsmip"
 // CHECK-MIPSEL: "-dynamic-linker" "{{.*}}/lib/ld.so.1"
 // CHECK-MIPSEL-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mipsel-linux-gnu -mnan=2008 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPSEL-NAN2008 %s
+// CHECK-MIPSEL-NAN2008: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPSEL-NAN2008: "-m" "elf32ltsmip"
+// CHECK-MIPSEL-NAN2008: "-dynamic-linker" "{{.*}}/lib/ld-linux-mipsn8.so.1"
+// CHECK-MIPSEL-NAN2008-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mipsel-linux-gnu -mcpu=mips32r6 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS32R6EL %s
+// CHECK-MIPS32R6EL: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPS32R6EL: "-m" "elf32ltsmip"
+// CHECK-MIPS32R6EL: "-dynamic-linker" "{{.*}}/lib/ld-linux-mipsn8.so.1"
+// CHECK-MIPS32R6EL-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64 %s
@@ -446,6 +536,7 @@
 // CHECK-MIPS64: "-m" "elf64btsmip"
 // CHECK-MIPS64: "-dynamic-linker" "{{.*}}/lib64/ld.so.1"
 // CHECK-MIPS64-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL %s
@@ -453,6 +544,21 @@
 // CHECK-MIPS64EL: "-m" "elf64ltsmip"
 // CHECK-MIPS64EL: "-dynamic-linker" "{{.*}}/lib64/ld.so.1"
 // CHECK-MIPS64EL-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64el-linux-gnu -mnan=2008 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL-NAN2008 %s
+// CHECK-MIPS64EL-NAN2008: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPS64EL-NAN2008: "-m" "elf64ltsmip"
+// CHECK-MIPS64EL-NAN2008: "-dynamic-linker" "{{.*}}/lib64/ld-linux-mipsn8.so.1"
+// CHECK-MIPS64EL-NAN2008-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64el-linux-gnu -mcpu=mips64r6 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64R6EL %s
+// CHECK-MIPS64R6EL: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPS64R6EL: "-m" "elf64ltsmip"
+// CHECK-MIPS64R6EL: "-dynamic-linker" "{{.*}}/lib64/ld-linux-mipsn8.so.1"
+// CHECK-MIPS64R6EL-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mabi=n32 \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64-N32 %s
@@ -460,6 +566,7 @@
 // CHECK-MIPS64-N32: "-m" "elf32btsmipn32"
 // CHECK-MIPS64-N32: "-dynamic-linker" "{{.*}}/lib32/ld.so.1"
 // CHECK-MIPS64-N32-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mabi=n32 \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL-N32 %s
@@ -468,6 +575,13 @@
 // CHECK-MIPS64EL-N32: "-dynamic-linker" "{{.*}}/lib32/ld.so.1"
 // CHECK-MIPS64EL-N32-NOT: "--hash-style={{gnu|both}}"
 //
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64el-linux-gnu -mabi=n32 \
+// RUN:   -mnan=2008 | FileCheck --check-prefix=CHECK-MIPS64EL-N32-NAN2008 %s
+// CHECK-MIPS64EL-N32-NAN2008: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPS64EL-N32-NAN2008: "-m" "elf32ltsmipn32"
+// CHECK-MIPS64EL-N32-NAN2008: "-dynamic-linker" "{{.*}}/lib32/ld-linux-mipsn8.so.1"
+// CHECK-MIPS64EL-N32-NAN2008-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=sparc-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-SPARCV8 %s
@@ -682,7 +796,7 @@
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SO %s
 // CHECK-ANDROID-SO: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-ANDROID-SO: "-Bsymbolic"
+// CHECK-ANDROID-SO-NOT: "-Bsymbolic"
 // CHECK-ANDROID-SO: "{{.*}}{{/|\\\\}}crtbegin_so.o"
 // CHECK-ANDROID-SO: "-L[[SYSROOT]]/usr/lib"
 // CHECK-ANDROID-SO-NOT: "gcc_s"
@@ -820,6 +934,87 @@
 // CHECK-ANDROID-32: "-dynamic-linker" "/system/bin/linker"
 // CHECK-ANDROID-64: "-dynamic-linker" "/system/bin/linker64"
 //
+// Test that -pthread does not add -lpthread on Android.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-androideabi -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-androideabi -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// CHECK-ANDROID-PTHREAD-NOT: -lpthread
+//
+// RUN: %clang -no-canonical-prefixes %t.o -### -o %t 2>&1 \
+// RUN:     --target=arm-linux-androideabi -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD-LINK %s
+// CHECK-ANDROID-PTHREAD-LINK-NOT: argument unused during compilation: '-pthread'
+//
 // Check linker invocation on Debian 6 MIPS 32/64-bit.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu \
@@ -869,6 +1064,44 @@
 // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/lib"
 // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib"
 //
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnuabi64 -mabi=n64 \
+// RUN:     --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64-GNUABI %s
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crt1.o"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crti.o"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9{{/|\\\\}}crtbegin.o"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/lib/mips64-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/mips64-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../.."
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/lib"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9{{/|\\\\}}crtend.o"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crtn.o"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnuabi64 -mabi=n64 \
+// RUN:     --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-GNUABI %s
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crt1.o"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crti.o"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9{{/|\\\\}}crtbegin.o"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/lib/mips64el-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/mips64el-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../.."
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/lib"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9{{/|\\\\}}crtend.o"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crtn.o"
+//
 // Test linker invocation for Freescale SDK (OpenEmbedded).
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=powerpc-fsl-linux \
@@ -936,3 +1169,9 @@
 // RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>& 1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PG %s
 // CHECK-PG: gcrt1.o
+
+// GCC forwards -u to the linker.
+// RUN: %clang -u asdf --target=x86_64-unknown-linux -### %s \
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>& 1 \
+// RUN:   | FileCheck --check-prefix=CHECK-u %s
+// CHECK-u: "-u" "asdf"
diff --git a/test/Driver/mips-abi.c b/test/Driver/mips-abi.c
index fd2b46f..f756324 100644
--- a/test/Driver/mips-abi.c
+++ b/test/Driver/mips-abi.c
@@ -1,36 +1,133 @@
 // Check passing Mips ABI options to the backend.
 //
+// RUN: %clang -target mips-linux-gnu -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-DEF %s
+// MIPS-DEF: "-target-cpu" "mips32r2"
+// MIPS-DEF: "-target-abi" "o32"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS64-DEF %s
+// MIPS64-DEF: "-target-cpu" "mips64r2"
+// MIPS64-DEF: "-target-abi" "n64"
+//
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:        -mabi=32 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-32 %s
+// MIPS-ABI-32: "-target-cpu" "mips32r2"
 // MIPS-ABI-32: "-target-abi" "o32"
 //
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:        -mabi=o32 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-O32 %s
+// MIPS-ABI-O32: "-target-cpu" "mips32r2"
 // MIPS-ABI-O32: "-target-abi" "o32"
 //
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:        -mabi=n32 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-N32 %s
+// MIPS-ABI-N32: "-target-cpu" "mips64r2"
 // MIPS-ABI-N32: "-target-abi" "n32"
 //
 // RUN: %clang -target mips64-linux-gnu -### -c %s \
 // RUN:        -mabi=64 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-64 %s
+// MIPS-ABI-64: "-target-cpu" "mips64r2"
 // MIPS-ABI-64: "-target-abi" "n64"
 //
 // RUN: %clang -target mips64-linux-gnu -### -c %s \
 // RUN:        -mabi=n64 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-N64 %s
+// MIPS-ABI-N64: "-target-cpu" "mips64r2"
 // MIPS-ABI-N64: "-target-abi" "n64"
 //
-// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN: not %clang -target mips64-linux-gnu -c %s \
 // RUN:        -mabi=o64 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-O64 %s
-// MIPS-ABI-O64: "-target-abi" "o64"
+// MIPS-ABI-O64: error: unknown target ABI 'o64'
 //
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:        -mabi=eabi 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-EABI %s
+// MIPS-ABI-EABI: "-target-cpu" "mips32r2"
 // MIPS-ABI-EABI: "-target-abi" "eabi"
+//
+// RUN: not %clang -target mips-linux-gnu -c %s \
+// RUN:        -mabi=unknown 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ABI-UNKNOWN %s
+// MIPS-ABI-UNKNOWN: error: unknown target ABI 'unknown'
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips1 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-1 %s
+// MIPS-ARCH-1: "-target-cpu" "mips1"
+// MIPS-ARCH-1: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips2 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-2 %s
+// MIPS-ARCH-2: "-target-cpu" "mips2"
+// MIPS-ARCH-2: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips3 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-3 %s
+// MIPS-ARCH-3: "-target-cpu" "mips3"
+// MIPS-ARCH-3: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips4 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-4 %s
+// MIPS-ARCH-4: "-target-cpu" "mips4"
+// MIPS-ARCH-4: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips5 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-5 %s
+// MIPS-ARCH-5: "-target-cpu" "mips5"
+// MIPS-ARCH-5: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips32 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-32 %s
+// MIPS-ARCH-32: "-target-cpu" "mips32"
+// MIPS-ARCH-32: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips32r2 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-32R2 %s
+// MIPS-ARCH-32R2: "-target-cpu" "mips32r2"
+// MIPS-ARCH-32R2: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips64 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-3264 %s
+// MIPS-ARCH-3264: "-target-cpu" "mips64"
+// MIPS-ARCH-3264: "-target-abi" "o32"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN:        -march=mips64 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-64 %s
+// MIPS-ARCH-64: "-target-cpu" "mips64"
+// MIPS-ARCH-64: "-target-abi" "n64"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN:        -march=mips64r2 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-64R2 %s
+// MIPS-ARCH-64R2: "-target-cpu" "mips64r2"
+// MIPS-ARCH-64R2: "-target-abi" "n64"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN:        -march=octeon 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-OCTEON %s
+// MIPS-ARCH-OCTEON: "-target-cpu" "octeon"
+// MIPS-ARCH-OCTEON: "-target-abi" "n64"
+//
+// RUN: not %clang -target mips64-linux-gnu -c %s \
+// RUN:        -march=mips32 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-6432 %s
+// MIPS-ARCH-6432: error: unknown target CPU 'mips32'
+//
+// RUN: not %clang -target mips-linux-gnu -c %s \
+// RUN:        -march=unknown 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-UNKNOWN %s
+// MIPS-ARCH-UNKNOWN: error: unknown target CPU 'unknown'
diff --git a/test/Driver/mips-as.c b/test/Driver/mips-as.c
index c825ee7..99e350e 100644
--- a/test/Driver/mips-as.c
+++ b/test/Driver/mips-as.c
@@ -2,30 +2,30 @@
 //
 // RUN: %clang -target mips-linux-gnu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS32-EB-AS %s
-// MIPS32-EB-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
-// MIPS32-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+// RUN:   | FileCheck -check-prefix=MIPS32R2-EB-AS %s
+// MIPS32R2-EB-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
+// MIPS32R2-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
 //
 // RUN: %clang -target mips-linux-gnu -### \
 // RUN:   -no-integrated-as -fPIC -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS32-EB-PIC %s
-// MIPS32-EB-PIC: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
-// MIPS32-EB-PIC: "-KPIC"
+// RUN:   | FileCheck -check-prefix=MIPS32R2-EB-PIC %s
+// MIPS32R2-EB-PIC: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
+// MIPS32R2-EB-PIC: "-KPIC"
 //
 // RUN: %clang -target mipsel-linux-gnu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS32-DEF-EL-AS %s
-// MIPS32-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS32R2-DEF-EL-AS %s
+// MIPS32R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EL"
 //
 // RUN: %clang -target mips64-linux-gnu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS64-EB-AS %s
-// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB"
+// RUN:   | FileCheck -check-prefix=MIPS64R2-EB-AS %s
+// MIPS64R2-EB-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB"
 //
 // RUN: %clang -target mips64el-linux-gnu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS64-DEF-EL-AS %s
-// MIPS64-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS64R2-DEF-EL-AS %s
+// MIPS64R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL"
 //
 // RUN: %clang -target mips-linux-gnu -mabi=eabi -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
@@ -39,19 +39,49 @@
 //
 // RUN: %clang -target mipsel-linux-gnu -mabi=32 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS32-EL-AS %s
-// MIPS32-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS32R2-EL-AS %s
+// MIPS32R2-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EL"
 //
 // RUN: %clang -target mips64el-linux-gnu -mabi=64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS64-EL-AS %s
-// MIPS64-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS64R2-EL-AS %s
+// MIPS64R2-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL"
 //
 // RUN: %clang -target mips-linux-gnu -march=mips32r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-32R2 %s
 // MIPS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 //
+// RUN: %clang -target mips64-linux-gnu -march=octeon -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-OCTEON %s
+// MIPS-OCTEON: as{{(.exe)?}}" "-march" "octeon" "-mabi" "64" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips1 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-1 %s
+// MIPS-ALIAS-1: as{{(.exe)?}}" "-march" "mips1" "-mabi" "32" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips2 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-2 %s
+// MIPS-ALIAS-2: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips3 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-3 %s
+// MIPS-ALIAS-3: as{{(.exe)?}}" "-march" "mips3" "-mabi" "32" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips4 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-4 %s
+// MIPS-ALIAS-4: as{{(.exe)?}}" "-march" "mips4" "-mabi" "32" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips5 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-5 %s
+// MIPS-ALIAS-5: as{{(.exe)?}}" "-march" "mips5" "-mabi" "32" "-EB"
+//
 // RUN: %clang -target mips-linux-gnu -mips32 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-32 %s
@@ -62,16 +92,26 @@
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-32R2 %s
 // MIPS-ALIAS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 //
-// RUN: %clang -target mips-linux-gnu -mips64 -### \
+// RUN: %clang -target mips-linux-gnu -mips32r6 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-32R6 %s
+// MIPS-ALIAS-32R6: as{{(.exe)?}}" "-march" "mips32r6" "-mabi" "32" "-EB"
+//
+// RUN: %clang -target mips64-linux-gnu -mips64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64 %s
 // MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
 //
-// RUN: %clang -target mips-linux-gnu -mips64r2 -### \
+// RUN: %clang -target mips64-linux-gnu -mips64r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R2 %s
 // MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB"
 //
+// RUN: %clang -target mips64-linux-gnu -mips64r6 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R6 %s
+// MIPS-ALIAS-64R6: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-EB"
+//
 // RUN: %clang -target mips-linux-gnu -mno-mips16 -mips16 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-16 %s
@@ -147,3 +187,51 @@
 // RUN:   | FileCheck -check-prefix=MIPS-NMSA %s
 // MIPS-NMSA: as{{(.exe)?}}"
 // MIPS-NMSA-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-mmsa"
+//
+// We've already tested MIPS32r2 and MIPS64r2 thoroughly. Do minimal tests on
+// the remaining CPU's since it was possible to pass on a -mabi with no value
+// when the CPU name is absent from a StringSwitch in getMipsCPUAndABI()
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips1 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS1-EB-AS %s
+// MIPS1-EB-AS: as{{(.exe)?}}" "-march" "mips1" "-mabi" "32" "-EB"
+// MIPS1-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips2 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS2-EB-AS %s
+// MIPS2-EB-AS: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EB"
+// MIPS2-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips3 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS3-EB-AS %s
+// MIPS3-EB-AS: as{{(.exe)?}}" "-march" "mips3" "-mabi" "64" "-EB"
+// MIPS3-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips4 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS4-EB-AS %s
+// MIPS4-EB-AS: as{{(.exe)?}}" "-march" "mips4" "-mabi" "64" "-EB"
+// MIPS4-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips5 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS5-EB-AS %s
+// MIPS5-EB-AS: as{{(.exe)?}}" "-march" "mips5" "-mabi" "64" "-EB"
+// MIPS5-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips32 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS32-EB-AS %s
+// MIPS32-EB-AS: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS32-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips32r6 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS32R6-EB-AS %s
+// MIPS32R6-EB-AS: as{{(.exe)?}}" "-march" "mips32r6" "-mabi" "32" "-EB"
+// MIPS32R6-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips64 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS64-EB-AS %s
+// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
+// MIPS64-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips64r6 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS64R6-EB-AS %s
+// MIPS64R6-EB-AS: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64" "-EB"
+// MIPS64R6-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c
index c21e975..2abb632 100644
--- a/test/Driver/mips-features.c
+++ b/test/Driver/mips-features.c
@@ -60,6 +60,16 @@
 // RUN:   | FileCheck --check-prefix=CHECK-NOMMSA %s
 // CHECK-NOMMSA: "-target-feature" "-msa"
 //
+// -modd-spreg
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-odd-spreg -modd-spreg 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MODDSPREG %s
+// CHECK-MODDSPREG: "-target-feature" "-nooddspreg"
+//
+// -mno-odd-spreg
+// RUN: %clang -target mips-linux-gnu -### -c %s -modd-spreg -mno-odd-spreg 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NOMODDSPREG %s
+// CHECK-NOMODDSPREG: "-target-feature" "+nooddspreg"
+//
 // -mfp64
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:     -mfp32 -mfp64 2>&1 \
diff --git a/test/Driver/mips-img.cpp b/test/Driver/mips-img.cpp
new file mode 100644
index 0000000..389e0f7
--- /dev/null
+++ b/test/Driver/mips-img.cpp
@@ -0,0 +1,163 @@
+// Check frontend and linker invocations on the IMG MIPS toolchain.
+//
+// = Big-endian, mips32r6
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-img-linux-gnu -mips32r6 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-32R6 %s
+// CHECK-BE-32R6: "-internal-isystem"
+// CHECK-BE-32R6: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-32R6: "-internal-isystem"
+// CHECK-BE-32R6: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu"
+// CHECK-BE-32R6: "-internal-isystem"
+// CHECK-BE-32R6: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-32R6: "-internal-externc-isystem"
+// CHECK-BE-32R6: "[[TC]]/include"
+// CHECK-BE-32R6: "-internal-externc-isystem"
+// CHECK-BE-32R6: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-32R6: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-32R6: "--sysroot=[[TC]]/../../../../sysroot"
+// CHECK-BE-32R6: "-dynamic-linker" "/lib/ld-linux-mipsn8.so.1"
+// CHECK-BE-32R6: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-32R6: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-32R6: "[[TC]]{{/|\\\\}}crtbegin.o"
+// CHECK-BE-32R6: "-L[[TC]]"
+// CHECK-BE-32R6: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/../lib"
+// CHECK-BE-32R6: "-L[[TC]]/../../../../sysroot/usr/lib/../lib"
+// CHECK-BE-32R6: "[[TC]]{{/|\\\\}}crtend.o"
+// CHECK-BE-32R6: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, mips32r6
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-img-linux-gnu -mips32r6 -EL \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LE-32R6 %s
+// CHECK-LE-32R6: "-internal-isystem"
+// CHECK-LE-32R6: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-LE-32R6: "-internal-isystem"
+// CHECK-LE-32R6: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/el"
+// CHECK-LE-32R6: "-internal-isystem"
+// CHECK-LE-32R6: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-LE-32R6: "-internal-externc-isystem"
+// CHECK-LE-32R6: "[[TC]]/include"
+// CHECK-LE-32R6: "-internal-externc-isystem"
+// CHECK-LE-32R6: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-LE-32R6: "{{.*}}ld{{(.exe)?}}"
+// CHECK-LE-32R6: "--sysroot=[[TC]]/../../../../sysroot/el"
+// CHECK-LE-32R6: "-dynamic-linker" "/lib/ld-linux-mipsn8.so.1"
+// CHECK-LE-32R6: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-LE-32R6: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-LE-32R6: "[[TC]]/el{{/|\\\\}}crtbegin.o"
+// CHECK-LE-32R6: "-L[[TC]]/el"
+// CHECK-LE-32R6: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/../lib/el"
+// CHECK-LE-32R6: "-L[[TC]]/../../../../sysroot/el/usr/lib/../lib"
+// CHECK-LE-32R6: "[[TC]]/el{{/|\\\\}}crtend.o"
+// CHECK-LE-32R6: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, mips64r6, N32
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-img-linux-gnu -mips64r6 -mabi=n32 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-64R6-N32 %s
+// CHECK-BE-64R6-N32: "-internal-isystem"
+// CHECK-BE-64R6-N32: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-64R6-N32: "-internal-isystem"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/mips64r6"
+// CHECK-BE-64R6-N32: "-internal-isystem"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-64R6-N32: "-internal-externc-isystem"
+// CHECK-BE-64R6-N32: "[[TC]]/include"
+// CHECK-BE-64R6-N32: "-internal-externc-isystem"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-64R6-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-64R6-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r6"
+// CHECK-BE-64R6-N32: "-dynamic-linker" "/lib32/ld-linux-mipsn8.so.1"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-64R6-N32: "[[TC]]/mips64r6{{/|\\\\}}crtbegin.o"
+// CHECK-BE-64R6-N32: "-L[[TC]]/mips64r6"
+// CHECK-BE-64R6-N32: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/mips64r6"
+// CHECK-BE-64R6-N32: "-L[[TC]]/../../../../sysroot/mips64r6/usr/lib"
+// CHECK-BE-64R6-N32: "[[TC]]/mips64r6{{/|\\\\}}crtend.o"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, mips64r6, N32
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-img-linux-gnu -mips64r6 -EL -mabi=n32 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LE-64R6-N32 %s
+// CHECK-LE-64R6-N32: "-internal-isystem"
+// CHECK-LE-64R6-N32: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-LE-64R6-N32: "-internal-isystem"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/mips64r6/el"
+// CHECK-LE-64R6-N32: "-internal-isystem"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-LE-64R6-N32: "-internal-externc-isystem"
+// CHECK-LE-64R6-N32: "[[TC]]/include"
+// CHECK-LE-64R6-N32: "-internal-externc-isystem"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-LE-64R6-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-LE-64R6-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r6/el"
+// CHECK-LE-64R6-N32: "-dynamic-linker" "/lib32/ld-linux-mipsn8.so.1"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/el/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/el/usr/lib{{/|\\\\}}crti.o"
+// CHECK-LE-64R6-N32: "[[TC]]/mips64r6/el{{/|\\\\}}crtbegin.o"
+// CHECK-LE-64R6-N32: "-L[[TC]]/mips64r6/el"
+// CHECK-LE-64R6-N32: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/mips64r6/el"
+// CHECK-LE-64R6-N32: "-L[[TC]]/../../../../sysroot/mips64r6/el/usr/lib"
+// CHECK-LE-64R6-N32: "[[TC]]/mips64r6/el{{/|\\\\}}crtend.o"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/el/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, mips64r6, N64
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-img-linux-gnu -mips64r6 -mabi=64 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-64R6-N64 %s
+// CHECK-BE-64R6-N64: "-internal-isystem"
+// CHECK-BE-64R6-N64: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-64R6-N64: "-internal-isystem"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/mips64r6/64"
+// CHECK-BE-64R6-N64: "-internal-isystem"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-64R6-N64: "-internal-externc-isystem"
+// CHECK-BE-64R6-N64: "[[TC]]/include"
+// CHECK-BE-64R6-N64: "-internal-externc-isystem"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-64R6-N64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-64R6-N64: "--sysroot=[[TC]]/../../../../sysroot/mips64r6/64"
+// CHECK-BE-64R6-N64: "-dynamic-linker" "/lib64/ld-linux-mipsn8.so.1"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-64R6-N64: "[[TC]]/mips64r6/64{{/|\\\\}}crtbegin.o"
+// CHECK-BE-64R6-N64: "-L[[TC]]/mips64r6/64"
+// CHECK-BE-64R6-N64: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/mips64r6/64"
+// CHECK-BE-64R6-N64: "-L[[TC]]/../../../../sysroot/mips64r6/64/usr/lib"
+// CHECK-BE-64R6-N64: "[[TC]]/mips64r6/64{{/|\\\\}}crtend.o"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, mips64r6, N64
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-img-linux-gnu -mips64r6 -EL -mabi=64 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LE-64R6-N64 %s
+// CHECK-LE-64R6-N64: "-internal-isystem"
+// CHECK-LE-64R6-N64: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-LE-64R6-N64: "-internal-isystem"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/mips64r6/64/el"
+// CHECK-LE-64R6-N64: "-internal-isystem"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-LE-64R6-N64: "-internal-externc-isystem"
+// CHECK-LE-64R6-N64: "[[TC]]/include"
+// CHECK-LE-64R6-N64: "-internal-externc-isystem"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-LE-64R6-N64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-LE-64R6-N64: "--sysroot=[[TC]]/../../../../sysroot/mips64r6/64/el"
+// CHECK-LE-64R6-N64: "-dynamic-linker" "/lib64/ld-linux-mipsn8.so.1"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/el/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/el/usr/lib{{/|\\\\}}crti.o"
+// CHECK-LE-64R6-N64: "[[TC]]/mips64r6/64/el{{/|\\\\}}crtbegin.o"
+// CHECK-LE-64R6-N64: "-L[[TC]]/mips64r6/64/el"
+// CHECK-LE-64R6-N64: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/mips64r6/64/el"
+// CHECK-LE-64R6-N64: "-L[[TC]]/../../../../sysroot/mips64r6/64/el/usr/lib"
+// CHECK-LE-64R6-N64: "[[TC]]/mips64r6/64/el{{/|\\\\}}crtend.o"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/el/usr/lib{{/|\\\\}}crtn.o"
diff --git a/test/Driver/mno-global-merge.c b/test/Driver/mno-global-merge.c
index ec9f69e..a17848f 100644
--- a/test/Driver/mno-global-merge.c
+++ b/test/Driver/mno-global-merge.c
@@ -2,11 +2,19 @@
 // RUN:   -mno-global-merge -### -fsyntax-only %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-NGM < %t %s
 
+// RUN: %clang -target arm64-apple-ios7 \
+// RUN:   -mno-global-merge -### -fsyntax-only %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-NGM < %t %s
+
 // CHECK-NGM: "-mno-global-merge"
 
 // RUN: %clang -target armv7-apple-darwin10 \
 // RUN:   -mglobal-merge -### -fsyntax-only %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-GM < %t %s
 
+// RUN: %clang -target arm64-apple-ios7 \
+// RUN:   -mglobal-merge -### -fsyntax-only %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-GM < %t %s
+
 // CHECK-GM-NOT: "-mglobal-merge"
 
diff --git a/test/Driver/msc-version.c b/test/Driver/msc-version.c
new file mode 100644
index 0000000..027072f
--- /dev/null
+++ b/test/Driver/msc-version.c
@@ -0,0 +1,42 @@
+// RUN: %clang -target i686-windows -fms-compatibility -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-NO-MSC-VERSION
+
+// CHECK-NO-MSC-VERSION: _MSC_BUILD 1
+// CHECK-NO-MSC-VERSION: _MSC_FULL_VER 170000000
+// CHECK-NO-MSC-VERSION: _MSC_VER 1700
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=1600 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION
+
+// CHECK-MSC-VERSION: _MSC_BUILD 1
+// CHECK-MSC-VERSION: _MSC_FULL_VER 160000000
+// CHECK-MSC-VERSION: _MSC_VER 1600
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=160030319 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-EXT
+
+// CHECK-MSC-VERSION-EXT: _MSC_BUILD 1
+// CHECK-MSC-VERSION-EXT: _MSC_FULL_VER 160030319
+// CHECK-MSC-VERSION-EXT: _MSC_VER 1600
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=14 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR
+
+// CHECK-MSC-VERSION-MAJOR: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR: _MSC_FULL_VER 140000000
+// CHECK-MSC-VERSION-MAJOR: _MSC_VER 1400
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=17.00 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR
+
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_FULL_VER 170000000
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_VER 1700
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=15.00.20706 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR-BUILD
+
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_FULL_VER 150020706
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_VER 1500
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=15.00.20706.01 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH
+
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_FULL_VER 150020706
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_VER 1500
+
diff --git a/test/Driver/openbsd.c b/test/Driver/openbsd.c
index 5fe27f3..6507838 100644
--- a/test/Driver/openbsd.c
+++ b/test/Driver/openbsd.c
@@ -59,3 +59,8 @@
 // CHECK-MIPS64-PIC: as{{.*}}" "-mabi" "64" "-EB" "-KPIC"
 // CHECK-MIPS64EL: as{{.*}}" "-mabi" "64" "-EL"
 // CHECK-MIPS64EL-PIC: as{{.*}}" "-mabi" "64" "-EL" "-KPIC"
+
+// Check that the integrated assembler is enabled for PowerPC
+// RUN: %clang -target powerpc-unknown-openbsd -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-POWERPC-AS %s
+// CHECK-POWERPC-AS-NOT: "-no-integrated-as"
diff --git a/test/Driver/pic.c b/test/Driver/pic.c
index c3b2bbe..3629cc4 100644
--- a/test/Driver/pic.c
+++ b/test/Driver/pic.c
@@ -201,7 +201,17 @@
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
 //
 // On OpenBSD, PIE is enabled by default, but can be disabled.
+// RUN: %clang -c %s -target amd64-pc-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
 // RUN: %clang -c %s -target i386-pc-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
+// RUN: %clang -c %s -target mips64-unknown-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
+// RUN: %clang -c %s -target mips64el-unknown-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
+// RUN: %clang -c %s -target powerpc-unknown-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target sparc64-unknown-openbsd -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
 // RUN: %clang -c %s -target i386-pc-openbsd -fno-pie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
diff --git a/test/Driver/ppc-features.cpp b/test/Driver/ppc-features.cpp
index a7ccedf..fa9a7ec 100644
--- a/test/Driver/ppc-features.cpp
+++ b/test/Driver/ppc-features.cpp
@@ -59,9 +59,12 @@
 // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=pwr7 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-14 %s
 // CHECK-14: "-target-feature" "-altivec"
 
-// RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=ppc64 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-15 %s
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=pwr8 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-15 %s
 // CHECK-15: "-target-feature" "-altivec"
 
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=ppc64 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-16 %s
+// CHECK-16: "-target-feature" "-altivec"
+
 // RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-qpx -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOQPX %s
 // CHECK-NOQPX: "-target-feature" "-qpx"
 
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index 405e3a6..786262c 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -134,6 +134,14 @@
 // 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:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID-SHARED-LIBASAN %s
+//
+// CHECK-ASAN-ANDROID-SHARED-LIBASAN-NOT: argument unused during compilation: '-shared-libasan'
+//
+// 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 \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID-SHARED %s
 //
@@ -189,6 +197,7 @@
 
 // RUN: %clangxx -fsanitize=undefined %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-CXX %s
 // CHECK-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
@@ -196,8 +205,10 @@
 // CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.san-i386.a" "-no-whole-archive"
 // CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan
 // CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.ubsan-i386.a.syms"
 // CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive"
 // CHECK-UBSAN-LINUX-CXX: "-lpthread"
+// CHECK-UBSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.ubsan_cxx-i386.a.syms"
 // CHECK-UBSAN-LINUX-CXX: "-lstdc++"
 
 // RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
@@ -228,11 +239,16 @@
 
 // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHARED %s
 // CHECK-UBSAN-LINUX-SHARED: "{{.*}}ld{{(.exe)?}}"
-// CHECK-UBSAN-LINUX-SHARED: libclang_rt.ubsan-i386.a"
+// CHECK-UBSAN-LINUX-SHARED-NOT: --export-dynamic
+// CHECK-UBSAN-LINUX-SHARED-NOT: --dynamic-list
+// CHECK-UBSAN-LINUX-SHARED-NOT: libclang_rt.ubsan-i386.a"
+// CHECK-UBSAN-LINUX-SHARED-NOT: --export-dynamic
+// CHECK-UBSAN-LINUX-SHARED-NOT: --dynamic-list
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target x86_64-unknown-linux -fsanitize=leak \
diff --git a/test/Driver/stack-protector.c b/test/Driver/stack-protector.c
index 7576c3a..7fecd1b 100644
--- a/test/Driver/stack-protector.c
+++ b/test/Driver/stack-protector.c
@@ -1,12 +1,12 @@
 // RUN: %clang -fno-stack-protector -### %s 2>&1 | FileCheck %s -check-prefix=NOSSP
-// NOSSP-NOT: "-stack-protector" "1"
+// NOSSP-NOT: "-stack-protector"
 // NOSSP-NOT: "-stack-protector-buffer-size" 
 
-// RUN: %clang -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=SSP
+// RUN: %clang -target i386-unknown-linux -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=SSP
 // SSP: "-stack-protector" "1"
 // SSP-NOT: "-stack-protector-buffer-size" 
 
-// RUN: %clang -fstack-protector --param ssp-buffer-size=16 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-BUF
+// RUN: %clang -target i386-unknown-linux -fstack-protector --param ssp-buffer-size=16 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-BUF
 // SSP-BUF: "-stack-protector" "1"
 // SSP-BUF: "-stack-protector-buffer-size" "16" 
 
@@ -16,9 +16,6 @@
 // RUN: %clang -target i386-pc-openbsd -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=OPENBSD_SPS
 // OPENBSD_SPS: "-stack-protector" "2"
 
-// RUN: %clang -target i386-pc-openbsd -fno-stack-protector -### %s 2>&1 | FileCheck %s -check-prefix=OPENBSD_OFF
-// OPENBSD_OFF-NOT: "-stack-protector"
-
 // RUN: %clang -fstack-protector-strong -### %s 2>&1 | FileCheck %s -check-prefix=SSP-STRONG
 // SSP-STRONG: "-stack-protector" "2"
 // SSP-STRONG-NOT: "-stack-protector-buffer-size" 
diff --git a/test/Driver/std.cpp b/test/Driver/std.cpp
index e98fd2c..aceda01 100644
--- a/test/Driver/std.cpp
+++ b/test/Driver/std.cpp
@@ -7,6 +7,8 @@
 // RUN: not %clang -std=gnu++11 %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX11 %s
 // RUN: not %clang -std=c++1y %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX1Y %s
 // RUN: not %clang -std=gnu++1y %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Y %s
+// RUN: not %clang -std=c++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX1Z %s
+// RUN: not %clang -std=gnu++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Z %s
 
 void f(int n) {
   typeof(n)();
@@ -30,3 +32,9 @@
 
 // GNUXX1Y-NOT: undeclared identifier 'typeof'
 // GNUXX1Y-NOT: undeclared identifier 'decltype'
+
+// CXX1Z: undeclared identifier 'typeof'
+// CXX1Z-NOT: undeclared identifier 'decltype'
+
+// GNUXX1Z-NOT: undeclared identifier 'typeof'
+// GNUXX1Z-NOT: undeclared identifier 'decltype'
diff --git a/test/FixIt/fixit-cxx0x.cpp b/test/FixIt/fixit-cxx0x.cpp
index 5fe7ca4..49a05ff 100644
--- a/test/FixIt/fixit-cxx0x.cpp
+++ b/test/FixIt/fixit-cxx0x.cpp
@@ -138,3 +138,23 @@
   register int n; // expected-warning {{'register' storage class specifier is deprecated}}
   return n;
 }
+
+namespace MisplacedParameterPack {
+  template <typename Args...> // expected-error {{'...' must immediately precede declared identifier}}
+  void misplacedEllipsisInTypeParameter(Args...);
+
+  template <typename... Args...> // expected-error {{'...' must immediately precede declared identifier}}
+  void redundantEllipsisInTypeParameter(Args...);
+
+  template <template <typename> class Args...> // expected-error {{'...' must immediately precede declared identifier}}
+  void misplacedEllipsisInTemplateTypeParameter(Args<int>...);
+
+  template <template <typename> class... Args...> // expected-error {{'...' must immediately precede declared identifier}}
+  void redundantEllipsisInTemplateTypeParameter(Args<int>...);
+
+  template <int N...> // expected-error {{'...' must immediately precede declared identifier}}
+  void misplacedEllipsisInNonTypeTemplateParameter();
+
+  template <int... N...> // expected-error {{'...' must immediately precede declared identifier}}
+  void redundantEllipsisInNonTypeTemplateParameter();
+}
diff --git a/test/FixIt/fixit-multiple-selector-warnings.m b/test/FixIt/fixit-multiple-selector-warnings.m
new file mode 100644
index 0000000..391728d
--- /dev/null
+++ b/test/FixIt/fixit-multiple-selector-warnings.m
@@ -0,0 +1,26 @@
+/* RUN: cp %s %t
+   RUN: %clang_cc1 -x objective-c -Wselector-type-mismatch -fixit %t
+   RUN: %clang_cc1 -x objective-c -Wselector-type-mismatch -Werror %t
+*/
+// rdar://16458579
+
+@interface I
+- (id) compare: (char) arg1;
+- length;
+@end
+
+@interface J
+- (id) compare: (id) arg1;
+@end
+
+SEL func()
+{
+        (void)@selector( compare: );
+        (void)@selector (compare:);
+        (void)@selector( compare:);
+        (void)@selector(compare: );
+        (void)@selector ( compare: );
+	return @selector(compare:);
+}
+
+
diff --git a/test/FixIt/fixit-objc-bridge-related.m b/test/FixIt/fixit-objc-bridge-related.m
new file mode 100644
index 0000000..36ccbca
--- /dev/null
+++ b/test/FixIt/fixit-objc-bridge-related.m
@@ -0,0 +1,43 @@
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin10  -fdiagnostics-parseable-fixits -x objective-c -fobjc-arc %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin10  -fdiagnostics-parseable-fixits -x objective-c++ -fobjc-arc %s 2>&1 | FileCheck %s
+// rdar://15932435
+
+typedef struct __attribute__((objc_bridge_related(UIColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef;
+
+@interface UIColor 
++ (UIColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+@end
+
+@interface UIButton
+@property(nonatomic,retain) UIColor *tintColor;
+@end
+
+void test(UIButton *myButton) {
+  CGColorRef cgColor = (CGColorRef)myButton.tintColor;
+  cgColor = myButton.tintColor;
+
+  cgColor = (CGColorRef)[myButton.tintColor CGColor];
+
+  cgColor = (CGColorRef)[myButton tintColor];
+}
+
+// CHECK: {17:36-17:36}:"["
+// CHECK: {17:54-17:54}:" CGColor]"
+
+// CHECK :{18:13-18:13}:"["
+// CHECK: {18:31-18:31}:" CGColor]"
+
+// CHECK :{22:25-22:25}:"["
+// CHECK :{22:45-22:45}:" CGColor]"
+
+@interface ImplicitPropertyTest
+- (UIColor *)tintColor;
+@end
+
+void test1(ImplicitPropertyTest *myImplicitPropertyTest) {
+  CGColorRef cgColor = (CGColorRef)[myImplicitPropertyTest tintColor];
+}
+
+// CHECK :{39:36-39:36}:"["
+// CHECK :{39:70-39:70}:" CGColor]"
diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp
index 6a8e7d1..f264938 100644
--- a/test/FixIt/fixit.cpp
+++ b/test/FixIt/fixit.cpp
@@ -204,7 +204,7 @@
 }
 
 template<template<typename> Foo, // expected-error {{template template parameter requires 'class' after the parameter list}}
-         template<typename> typename Bar, // expected-error {{template template parameter requires 'class' after the parameter list}}
+         template<typename> typename Bar, // expected-warning {{template template parameter using 'typename' is a C++1z extension}}
          template<typename> struct Baz> // expected-error {{template template parameter requires 'class' after the parameter list}}
 void func();
 
diff --git a/test/FixIt/format-darwin.m b/test/FixIt/format-darwin.m
index f5205643..170bb09 100644
--- a/test/FixIt/format-darwin.m
+++ b/test/FixIt/format-darwin.m
@@ -1,11 +1,8 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fblocks -Wformat-non-iso -verify %s
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -Wformat-non-iso -verify %s
 
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck %s
-
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK-32 %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK-64 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-32 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-64 %s
 
 int printf(const char * restrict, ...);
 
@@ -25,10 +22,16 @@
 
 typedef SInt32 OSStatus;
 
+typedef enum NSIntegerEnum : NSInteger {
+  EnumValueA,
+  EnumValueB
+} NSIntegerEnum;
+
 NSInteger getNSInteger();
 NSUInteger getNSUInteger();
 SInt32 getSInt32();
 UInt32 getUInt32();
+NSIntegerEnum getNSIntegerEnum();
 
 void testCorrectionInAllCases() {
   printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
@@ -47,6 +50,11 @@
 
   // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:16}:"(unsigned int)"
+
+  printf("%s", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
 }
 
 @interface Foo {
@@ -107,6 +115,11 @@
 
   // CHECK-64: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:14}:"%u"
   // CHECK-64: fix-it:"{{.*}}":{[[@LINE-12]]:17-[[@LINE-12]]:17}:"(unsigned int)"
+
+  printf("%d", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK-64: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
 }
 
 void testPreserveHex() {
@@ -135,6 +148,7 @@
   printf("%lu", getNSUInteger()); // no-warning
   printf("%d", getSInt32()); // no-warning
   printf("%u", getUInt32()); // no-warning
+  printf("%ld", getNSIntegerEnum()); // no-warning
 }
 
 #else
@@ -149,6 +163,10 @@
   // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(unsigned long)"
   // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(int)"
   // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(unsigned int)"
+
+  printf("%ld", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK-32: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:"(long)"
 }
 
 void testPreserveHex() {
@@ -164,6 +182,7 @@
   printf("%u", getNSUInteger()); // no-warning
   printf("%ld", getSInt32()); // no-warning
   printf("%lu", getUInt32()); // no-warning
+  printf("%d", getNSIntegerEnum()); // no-warning
 }
 
 void testSignedness(NSInteger i, NSUInteger u) {
@@ -194,6 +213,11 @@
 
   // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:24}:"(unsigned int)"
+
+  printf("%s", (NSIntegerEnum)0); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:31}:"(long)"
 }
 
 void testCapitals() {
diff --git a/test/FixIt/format.m b/test/FixIt/format.m
index 5e46360..d07ee36 100644
--- a/test/FixIt/format.m
+++ b/test/FixIt/format.m
@@ -82,14 +82,14 @@
 
 typedef enum : int { NSUTF8StringEncoding = 8 } NSStringEncoding;
 void test_fixed_enum_correction(NSStringEncoding x) {
-  NSLog(@"%@", x); // expected-warning{{format specifies type 'id' but the argument has type 'NSStringEncoding'}}
+  NSLog(@"%@", x); // expected-warning{{format specifies type 'id' but the argument has underlying type 'int'}}
   // CHECK: fix-it:"{{.*}}":{85:11-85:13}:"%d"
 }
 
 typedef __SIZE_TYPE__ size_t;
 enum SomeSize : size_t { IntegerSize = sizeof(int) };
 void test_named_fixed_enum_correction(enum SomeSize x) {
-  NSLog(@"%@", x); // expected-warning{{format specifies type 'id' but the argument has type 'enum SomeSize'}}
+  NSLog(@"%@", x); // expected-warning{{format specifies type 'id' but the argument has underlying type 'size_t' (aka}}
   // CHECK: fix-it:"{{.*}}":{92:11-92:13}:"%zu"
 }
 
@@ -228,3 +228,29 @@
 
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:14}:"%+ld"
 }
+
+void testEnum() {
+  typedef enum {
+    ImplicitA = 1,
+    ImplicitB = 2
+  } Implicit;
+
+  typedef enum {
+    ImplicitLLA = 0,
+    ImplicitLLB = ~0ULL
+  } ImplicitLongLong;
+
+  typedef enum : short {
+    ExplicitA = 0,
+    ExplicitB
+  } ExplicitShort;
+
+  printf("%f", (Implicit)0); // expected-warning{{format specifies type 'double' but the argument has underlying type}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%{{[du]}}"
+
+  printf("%f", (ImplicitLongLong)0); // expected-warning{{format specifies type 'double' but the argument has underlying type}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%{{l*[du]}}"
+
+  printf("%f", (ExplicitShort)0); // expected-warning{{format specifies type 'double' but the argument has underlying type 'short'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%hd"
+}
diff --git a/test/Format/style-on-command-line.cpp b/test/Format/style-on-command-line.cpp
index 19add89..007022e 100644
--- a/test/Format/style-on-command-line.cpp
+++ b/test/Format/style-on-command-line.cpp
@@ -12,19 +12,23 @@
 // RUN: [ ! -e %T/_clang-format ] || rm %T/_clang-format
 // RUN: printf "BasedOnStyle: google\nIndentWidth: 6\n" > %T/_clang-format
 // RUN: clang-format -style=file %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK7 %s
+// RUN: clang-format -style="{BasedOnStyle: LLVM, PointerBindsToType: true}" %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK8 %s
+// RUN: clang-format -style="{BasedOnStyle: WebKit, PointerBindsToType: false}" %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK9 %s
 void f() {
 // CHECK1: {{^        int\* i;$}}
 // CHECK2: {{^       int \*i;$}}
 // CHECK3: Unknown value for BasedOnStyle: invalid
-// CHECK3: Error parsing -style: Invalid argument, using LLVM style
+// CHECK3: Error parsing -style: {{I|i}}nvalid argument, using LLVM style
 // CHECK3: {{^  int \*i;$}}
-// CHECK4: Error parsing -style: Invalid argument, using LLVM style
+// CHECK4: Error parsing -style: {{I|i}}nvalid argument, using LLVM style
 // CHECK4: {{^  int \*i;$}}
 // CHECK5: {{^     int\* i;$}}
-// CHECK6: {{^Error reading .*\.clang-format: Invalid argument}}
+// CHECK6: {{^Error reading .*\.clang-format: (I|i)nvalid argument}}
 // CHECK6: {{^Can't find usable .clang-format, using webkit style$}}
 // CHECK6: {{^    int\* i;$}}
 // CHECK7: {{^      int\* i;$}}
+// CHECK8: {{^  int\* i;$}}
+// CHECK9: {{^    int \*i;$}}
 int*i;
 int j;
 }
diff --git a/test/Frontend/backend-diagnostic.c b/test/Frontend/backend-diagnostic.c
index 8b61c03..1fe4fdb 100644
--- a/test/Frontend/backend-diagnostic.c
+++ b/test/Frontend/backend-diagnostic.c
@@ -6,21 +6,18 @@
 //
 // RUN: not %clang_cc1 %s -mllvm -warn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin 2> %t.err
 // RUN: FileCheck < %t.err %s --check-prefix=REGULAR --check-prefix=ASM
-// RUN: not %clang_cc1 %s -mllvm -warn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin -Werror=frame-larger-than 2> %t.err
+// RUN: not %clang_cc1 %s -mllvm -warn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin -Werror=frame-larger-than= 2> %t.err
 // RUN: FileCheck < %t.err %s --check-prefix=PROMOTE --check-prefix=ASM
-// RUN: not %clang_cc1 %s -mllvm -warn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin -Wno-frame-larger-than 2> %t.err
+// RUN: not %clang_cc1 %s -mllvm -warn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin -Wno-frame-larger-than= 2> %t.err
 // RUN: FileCheck < %t.err %s --check-prefix=IGNORE --check-prefix=ASM
 //
-// Currently the stack size reporting cannot be checked with -verify because
-//  no source location is attached to the diagnostic. Therefore do not emit
-// them for the -verify test for now.
 // RUN: %clang_cc1 %s -S -o - -triple=i386-apple-darwin -verify -no-integrated-as
 
 extern void doIt(char *);
 
-// REGULAR: warning: stack size exceeded ({{[0-9]+}}) in stackSizeWarning
-// PROMOTE: error: stack size exceeded ({{[0-9]+}}) in stackSizeWarning
-// IGNORE-NOT: stack size exceeded ({{[0-9]+}}) in stackSizeWarning
+// REGULAR: warning: stack frame size of {{[0-9]+}} bytes in function 'stackSizeWarning'
+// PROMOTE: error: stack frame size of {{[0-9]+}} bytes in function 'stackSizeWarning'
+// IGNORE-NOT: stack frame size of {{[0-9]+}} bytes in function 'stackSizeWarning'
 void stackSizeWarning() {
   char buffer[80];
   doIt(buffer);
diff --git a/test/Frontend/disable-output.c b/test/Frontend/disable-output.c
new file mode 100644
index 0000000..786ac77
--- /dev/null
+++ b/test/Frontend/disable-output.c
@@ -0,0 +1,7 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -emit-llvm-only -triple=i386-apple-darwin -o %t
+// RUN: not rm %t
+// RUN: %clang_cc1 %s -emit-codegen-only -triple=i386-apple-darwin -o %t
+// RUN: not rm %t
+
+// Test that output is not generated when emission is disabled.
diff --git a/test/Frontend/exceptions.c b/test/Frontend/exceptions.c
new file mode 100644
index 0000000..4bbaaa3
--- /dev/null
+++ b/test/Frontend/exceptions.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fms-compatibility -fexceptions -fcxx-exceptions -verify %s
+// expected-no-diagnostics
+
+#if defined(__EXCEPTIONS)
+#error __EXCEPTIONS should not be defined.
+#endif
diff --git a/test/Frontend/ir-support.c b/test/Frontend/ir-support.c
new file mode 100644
index 0000000..f69161e
--- /dev/null
+++ b/test/Frontend/ir-support.c
@@ -0,0 +1,19 @@
+// Test that we can consume LLVM IR/bitcode in the frontend and produce
+// equivalent output to a standard compilation.
+
+// We strip differing '.file' directives before comparing.
+
+// Reference output:
+// RUN: %clang_cc1 -S -o - %s | grep -v '\.file' > %t.s
+
+// LLVM bitcode:
+// RUN: %clang_cc1 -emit-llvm-bc -o %t.bc %s
+// RUN: %clang_cc1 -S -o - %t.bc | grep -v '\.file' > %t.bc.s
+// RUN: diff %t.s %t.bc.s
+
+// LLVM IR source code:
+// RUN: %clang_cc1 -emit-llvm -o %t.ll %s
+// RUN: %clang_cc1 -S -o - %t.ll | grep -v '\.file' > %t.ll.s
+// RUN: diff %t.s %t.ll.s
+
+int f() { return 0; }
diff --git a/test/Frontend/lit.local.cfg b/test/Frontend/lit.local.cfg
index 4c13598..c11fb6d 100644
--- a/test/Frontend/lit.local.cfg
+++ b/test/Frontend/lit.local.cfg
@@ -1 +1 @@
-config.suffixes = ['.c', '.cpp', '.m', '.mm', '.ll', '.bc']
+config.suffixes = ['.c', '.cpp', '.m', '.mm', '.ll']
diff --git a/test/Frontend/optimization-remark-line-directive.c b/test/Frontend/optimization-remark-line-directive.c
index b4b1b92..f4c0011 100644
--- a/test/Frontend/optimization-remark-line-directive.c
+++ b/test/Frontend/optimization-remark-line-directive.c
@@ -2,14 +2,11 @@
 // directives. We cannot map #line directives back to
 // a SourceLocation.
 
-// RUN: %clang -c %s -Rpass=inline -O0 -S -gmlt -o /dev/null 2> %t.err
-// RUN: FileCheck < %t.err %s --check-prefix=INLINE-INVALID-LOC
-//
+// RUN: %clang_cc1 %s -Rpass=inline -gline-tables-only -dwarf-column-info -emit-llvm-only -verify
+
 int foo(int x, int y) __attribute__((always_inline));
 int foo(int x, int y) { return x + y; }
 
+// expected-remark@+2 {{foo inlined into bar}} expected-note@+2 {{could not determine the original source location for /bad/path/to/original.c:1230:25}}
 #line 1230 "/bad/path/to/original.c"
 int bar(int j) { return foo(j, j - 2); }
-
-// INLINE-INVALID-LOC: {{^remark: foo inlined into bar}}
-// INLINE-INVALID-LOC: note: could not determine the original source location for /bad/path/to/original.c:1230:0
diff --git a/test/Frontend/optimization-remark.c b/test/Frontend/optimization-remark.c
index 3a62db0..e512253 100644
--- a/test/Frontend/optimization-remark.c
+++ b/test/Frontend/optimization-remark.c
@@ -1,18 +1,36 @@
-// This file tests the -Rpass= flag with the inliner. The test is
-// designed to always trigger the inliner, so it should be independent
-// of the optimization level.
+// This file tests the -Rpass family of flags (-Rpass, -Rpass-missed
+// and -Rpass-analysis) with the inliner. The test is designed to
+// always trigger the inliner, so it should be independent of the
+// optimization level.
 
-// RUN: %clang_cc1 %s -Rpass=inline -O0 -gline-tables-only -emit-obj -verify -S -o /dev/null 2> %t.err
+// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O0 -emit-llvm-only -verify
+// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O0 -emit-llvm-only -gline-tables-only -verify
+// RUN: %clang_cc1 %s -Rpass=inline -emit-llvm -o - 2>/dev/null | FileCheck %s
 
-// RUN: %clang -c %s -Rpass=inline -O0 -S -o /dev/null 2> %t.err
-// RUN: FileCheck < %t.err %s --check-prefix=INLINE-NO-LOC
+// -Rpass should produce source location annotations, exclusively (just
+// like -gmlt).
+// CHECK: , !dbg !
+// CHECK-NOT: DW_TAG_base_type
+
+// But llvm.dbg.cu should be missing (to prevent writing debug info to
+// the final output).
+// CHECK-NOT: !llvm.dbg.cu = !{
 
 int foo(int x, int y) __attribute__((always_inline));
-
 int foo(int x, int y) { return x + y; }
 
-// expected-remark@+1 {{foo inlined into bar}}
-int bar(int j) { return foo(j, j - 2); }
+float foz(int x, int y) __attribute__((noinline));
+float foz(int x, int y) { return x * y; }
 
-// INLINE-NO-LOC: {{^remark: foo inlined into bar}}
-// INLINE-NO-LOC: note: use -gline-tables-only -gcolumn-info to track
+// The negative diagnostics are emitted twice because the inliner runs
+// twice.
+//
+int bar(int j) {
+// expected-remark@+6 {{foz should never be inlined (cost=never)}}
+// expected-remark@+5 {{foz will not be inlined into bar}}
+// expected-remark@+4 {{foz should never be inlined}}
+// expected-remark@+3 {{foz will not be inlined into bar}}
+// expected-remark@+2 {{foo should always be inlined}}
+// expected-remark@+1 {{foo inlined into bar}}
+  return foo(j, j - 2) * foz(j - 2, j);
+}
diff --git a/test/Frontend/print-header-includes.c b/test/Frontend/print-header-includes.c
index aa3e397..e248c76 100644
--- a/test/Frontend/print-header-includes.c
+++ b/test/Frontend/print-header-includes.c
@@ -1,12 +1,12 @@
-// RUN: %clang_cc1 -include Inputs/test3.h -E -H -o %t.out %s 2> %t.err
-// RUN: FileCheck < %t.err %s
+// RUN: %clang_cc1 -include Inputs/test3.h -E -H -o %t.out %s 2> %t.stderr
+// RUN: FileCheck < %t.stderr %s
 
 // CHECK-NOT: test3.h
 // CHECK: . {{.*test.h}}
 // CHECK: .. {{.*test2.h}}
 
-// RUN: %clang_cc1 -include Inputs/test3.h -E --show-includes -o %t.out %s 2> %t.err
-// RUN: FileCheck --check-prefix=MS < %t.err %s
+// RUN: %clang_cc1 -include Inputs/test3.h -E --show-includes -o %t.out %s > %t.stdout
+// RUN: FileCheck --check-prefix=MS < %t.stdout %s
 // MS-NOT: test3.h
 // MS: Note: including file: {{.*test.h}}
 // MS: Note: including file:  {{.*test2.h}}
diff --git a/test/Frontend/stdlang.c b/test/Frontend/stdlang.c
new file mode 100644
index 0000000..71997f1
--- /dev/null
+++ b/test/Frontend/stdlang.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -x cuda -std=c++11 -DCUDA %s
+// RUN: %clang_cc1 -x cl -std=c99 -DOPENCL %s
+// expected-no-diagnostics
+
+#if defined(CUDA)
+  __attribute__((device)) void f_device();
+#elif defined(OPENCL)
+  kernel void func(void);
+#endif
diff --git a/test/Frontend/verify.c b/test/Frontend/verify.c
index 4bd0c90..e2e7894 100644
--- a/test/Frontend/verify.c
+++ b/test/Frontend/verify.c
@@ -134,9 +134,18 @@
 // expected-warning@verify-directive.h: {{ }}
 // expected-error@-1 {{missing or invalid line number}}
 
+// expected-warning@verify-directive.h:0 {{ }}
+// expected-error@-1 {{missing or invalid line number}}
+
+// expected-warning@verify-directive.h:0*{{ }}
+// expected-error@-1 {{missing or invalid line number}}
+
+// expected-warning@verify-directive.h:*0{{ }}
+// syntactically ok -- means match in any line for 0 occurrences.
+
 // expected-warning@verify-directive.h:1 {{diagnostic}}
 
 //      CHECK8: error: 'warning' diagnostics expected but not seen:
-// CHECK8-NEXT:   File {{.*}}verify-directive.h Line 1 (directive at {{.*}}verify.c:137): diagnostic
+// CHECK8-NEXT:   File {{.*}}verify-directive.h Line 1 (directive at {{.*}}verify.c:146): diagnostic
 // CHECK8-NEXT: 1 error generated.
 #endif
diff --git a/test/Frontend/verify2.c b/test/Frontend/verify2.c
index 73eda4d..075a2ab 100644
--- a/test/Frontend/verify2.c
+++ b/test/Frontend/verify2.c
@@ -14,7 +14,26 @@
 
 //      CHECK: error: no expected directives found: consider use of 'expected-no-diagnostics'
 // CHECK-NEXT: error: 'error' diagnostics seen but not expected:
-// CHECK-NEXT:   Line 1: header
+// CHECK-NEXT:   Line 5: header
 // CHECK-NEXT:   Line 10: source
 // CHECK-NEXT: 3 errors generated.
 #endif
+
+#ifdef CHECK2
+// RUN: not %clang_cc1 -DCHECK2 -verify %s 2>&1 | FileCheck -check-prefix=CHECK2 %s
+
+// The following checks that -verify can match "any line" in an included file.
+// The location of the diagnostic need therefore only match in the file, not to
+// a specific line number.  This is useful where -verify is used as a testing
+// tool for 3rd-party libraries where headers may change and the specific line
+// number of a diagnostic in a header is not important.
+
+// expected-error@verify2.h:* {{header}}
+// expected-error@verify2.h:* {{unknown}}
+
+//      CHECK2: error: 'error' diagnostics expected but not seen:
+// CHECK2-NEXT:   File {{.*}}verify2.h Line * (directive at {{.*}}verify2.c:32): unknown
+// CHECK2-NEXT: error: 'error' diagnostics seen but not expected:
+// CHECK2-NEXT:   File {{.*}}verify2.c Line 10: source
+// CHECK2-NEXT: 2 errors generated.
+#endif
diff --git a/test/Frontend/verify2.h b/test/Frontend/verify2.h
index 8acbf6e..a426722 100644
--- a/test/Frontend/verify2.h
+++ b/test/Frontend/verify2.h
@@ -1,5 +1,5 @@
-#error header
-
 #if 0
 // expected-error {{should be ignored}}
 #endif
+
+#error header
diff --git a/test/Headers/arm-acle-header.c b/test/Headers/arm-acle-header.c
new file mode 100644
index 0000000..523e77e
--- /dev/null
+++ b/test/Headers/arm-acle-header.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple armv7 -target-cpu cortex-a15 -fsyntax-only -ffreestanding %s
+// RUN: %clang_cc1 -triple aarch64 -target-cpu cortex-a53 -fsyntax-only -ffreestanding %s
+// RUN: %clang_cc1 -x c++ -triple armv7 -target-cpu cortex-a15 -fsyntax-only -ffreestanding %s
+// RUN: %clang_cc1 -x c++ -triple aarch64 -target-cpu cortex-a57 -fsyntax-only -ffreestanding %s
+// expected-no-diagnostics
+
+#include <arm_acle.h>
diff --git a/test/Headers/ms-intrin.cpp b/test/Headers/ms-intrin.cpp
index 03f57a5..d2cc627 100644
--- a/test/Headers/ms-intrin.cpp
+++ b/test/Headers/ms-intrin.cpp
@@ -8,6 +8,11 @@
 // RUN:     -ffreestanding -fsyntax-only -Werror \
 // RUN:     -isystem %S/Inputs/include %s
 
+// RUN: %clang_cc1 -triple thumbv7--windows \
+// RUN:     -ffreestanding -fsyntax-only -fms-compatibility -fmsc-version=1700 \
+// RUN:     -Werror \
+// RUN:     -isystem %S/Inputs/include %s
+
 // Intrin.h needs size_t, but -ffreestanding prevents us from getting it from
 // stddef.h.  Work around it with this typedef.
 typedef __SIZE_TYPE__ size_t;
diff --git a/test/Index/attributes-cuda.cu b/test/Index/attributes-cuda.cu
new file mode 100644
index 0000000..953ef3d
--- /dev/null
+++ b/test/Index/attributes-cuda.cu
@@ -0,0 +1,15 @@
+// RUN: c-index-test -test-load-source all -x cuda %s | FileCheck %s
+
+__attribute__((device)) void f_device();
+__attribute__((global)) void f_global();
+__attribute__((constant)) int* g_constant;
+__attribute__((host)) void f_host();
+
+// CHECK:       attributes-cuda.cu:3:30: FunctionDecl=f_device:3:30
+// CHECK-NEXT:  attributes-cuda.cu:3:16: attribute(device)
+// CHECK:       attributes-cuda.cu:4:30: FunctionDecl=f_global:4:30
+// CHECK-NEXT:  attributes-cuda.cu:4:16: attribute(global)
+// CHECK:       attributes-cuda.cu:5:32: VarDecl=g_constant:5:32 (Definition)
+// CHECK-NEXT:  attributes-cuda.cu:5:16: attribute(constant)
+// CHECK:       attributes-cuda.cu:6:28: FunctionDecl=f_host:6:28
+// CHECK-NEXT:  attributes-cuda.cu:6:16: attribute(host)
diff --git a/test/Index/index-pch-objc.m b/test/Index/index-pch-objc.m
new file mode 100644
index 0000000..b9b741f
--- /dev/null
+++ b/test/Index/index-pch-objc.m
@@ -0,0 +1,10 @@
+// RUN: c-index-test -write-pch %t.pch -target x86_64-apple-darwin10 %s
+// RUN: env LIBCLANG_NOTHREADS=1 c-index-test -index-tu %t.pch | FileCheck %s
+
+@interface SomeClass
+@property (retain) id foo;
+@end
+@implementation SomeClass
+@end
+
+// CHECK: [indexDeclaration]: kind: objc-ivar | name: _foo
diff --git a/test/Lexer/cxx1z-trigraphs.cpp b/test/Lexer/cxx1z-trigraphs.cpp
new file mode 100644
index 0000000..410626f
--- /dev/null
+++ b/test/Lexer/cxx1z-trigraphs.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+// RUN: %clang_cc1 -std=c++1z %s -trigraphs -fsyntax-only
+
+??= define foo ; // expected-error {{}} expected-warning {{trigraph ignored}}
+
+static_assert("??="[0] == '#', ""); // expected-error {{failed}} expected-warning {{trigraph ignored}}
+
+// ??/
+error here; // expected-error {{}}
diff --git a/test/Lexer/ms-extensions.c b/test/Lexer/ms-extensions.c
index 377d2d5..ebcf0f4 100644
--- a/test/Lexer/ms-extensions.c
+++ b/test/Lexer/ms-extensions.c
@@ -1,11 +1,15 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
 // RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i386-pc-win32 -fms-compatibility %s
 
 __int8 x1  = 3i8;
 __int16 x2 = 4i16;
 __int32 x3 = 5i32;
 __int64 x5 = 0x42i64;
 __int64 x6 = 0x42I64;
+#ifndef __SIZEOF_INT128__
+// expected-error@+2 {{__int128 is not supported on this target}}
+#endif
 __int64 x4 = 70000000i128;
 
 __int64 y = 0x42i64u;  // expected-error {{invalid suffix}}
@@ -13,6 +17,10 @@
 __int64 z = 9Li64;  // expected-error {{invalid suffix}}
 __int64 q = 10lli64;  // expected-error {{invalid suffix}}
 
+__complex double c1 = 1i;
+__complex double c2 = 1.0i;
+__complex float c3 = 1.0if;
+
 // radar 7562363
 #define ULLONG_MAX 0xffffffffffffffffui64
 #define UINT 0xffffffffui32
diff --git a/test/Lexer/warn-date-time.c b/test/Lexer/warn-date-time.c
new file mode 100644
index 0000000..96fb553
--- /dev/null
+++ b/test/Lexer/warn-date-time.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -Wdate-time -Wno-builtin-macro-redefined %s -verify -E
+// RUN: %clang_cc1 -Wdate-time -Wno-builtin-macro-redefined %s -DIS_SYSHEADER -verify -E
+// RUN: not %clang_cc1 -Werror=date-time -Wno-builtin-macro-redefined %s -DIS_SYSHEADER -E 2>&1 | grep 'error: expansion' | count 3
+
+
+#ifdef IS_HEADER
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+#endif
+
+__TIME__ // expected-warning {{expansion of date or time macro is not reproducible}}
+__DATE__  // expected-warning {{expansion of date or time macro is not reproducible}}
+__TIMESTAMP__ // expected-warning {{expansion of date or time macro is not reproducible}}
+
+#define __TIME__
+__TIME__
+
+#else
+
+#define IS_HEADER
+#include __FILE__
+#endif
diff --git a/test/Misc/ast-dump-attr.cpp b/test/Misc/ast-dump-attr.cpp
index dde7ba3..1aa6adf 100644
--- a/test/Misc/ast-dump-attr.cpp
+++ b/test/Misc/ast-dump-attr.cpp
@@ -108,7 +108,13 @@
 extern "C" int printf(const char *format, ...);
 // CHECK: FunctionDecl{{.*}}printf
 // CHECK-NEXT: ParmVarDecl{{.*}}format{{.*}}'const char *'
-// CHECK-NEXT: FormatAttr{{.*}}printf 1 2 Implicit
+// CHECK-NEXT: FormatAttr{{.*}}Implicit printf 1 2
+
+alignas(8) extern int x;
+extern int x;
+// CHECK: VarDecl{{.*}} x 'int'
+// CHECK: VarDecl{{.*}} x 'int'
+// CHECK-NEXT: AlignedAttr{{.*}} Inherited
 }
 
 int __attribute__((cdecl)) TestOne(void), TestTwo(void);
diff --git a/test/Misc/ast-dump-color.cpp b/test/Misc/ast-dump-color.cpp
index d49f0d7..0bb6dd0 100644
--- a/test/Misc/ast-dump-color.cpp
+++ b/test/Misc/ast-dump-color.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux -std=c++11 -ast-dump -fcolor-diagnostics %s | FileCheck --strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-pc-linux -std=c++11 -ast-dump -fcolor-diagnostics %s | FileCheck --strict-whitespace %s
 // REQUIRES: ansi-escape-sequences
 
 /// <a>Hello</a>
@@ -25,6 +25,10 @@
 } mu1, mu2;
 int TestExpr __attribute__((guarded_by(mu1)));
 
+struct Invalid {
+  __attribute__((noinline)) Invalid(error);
+} Invalid;
+
 //CHECK: {{^}}[[Blue:.\[0;34m]][[RESET:.\[0m]][[GREEN:.\[0;1;32m]]TranslationUnitDecl[[RESET]][[Yellow:.\[0;33m]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]] implicit[[CYAN:.\[0;1;36m]] __int128_t[[RESET]] [[Green:.\[0;32m]]'__int128'[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]] implicit[[CYAN]] __uint128_t[[RESET]] [[Green]]'unsigned __int128'[[RESET]]{{$}}
@@ -71,17 +75,29 @@
 //CHECK: {{^}}[[Blue]]| |   | `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:22[[RESET]]> Text=" Another variable"{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:23:6[[RESET]], [[Yellow]]col:44[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| |     `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:44[[RESET]]> Text=" Like the other variable, but different"{{$}}
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit[[CYAN]] Mutex[[RESET]] [[Green]]'void (void)'[[RESET]] inline{{.*$}}
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit used[[CYAN]] Mutex[[RESET]] [[Green]]'void (void)'[[RESET]] inline{{.*$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit[[CYAN]] Mutex[[RESET]] [[Green]]'void (const class Mutex &)'[[RESET]] inline{{ .*$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] [[Green]]'const class Mutex &'[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit[[CYAN]] Mutex[[RESET]] [[Green]]'void (class Mutex &&)'[[RESET]] inline{{ .*$}}
 //CHECK: {{^}}[[Blue]]|   `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] [[Green]]'class Mutex &&'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]> [[Yellow]]col:3[[RESET]][[CYAN]] mu1[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]> [[Yellow]]col:3[[RESET]] referenced[[CYAN]] mu1[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:8[[RESET]]> [[Yellow]]col:8[[RESET]][[CYAN]] mu2[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]`-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:26:1[[RESET]], [[Yellow]]col:5[[RESET]]> [[Yellow]]col:5[[RESET]][[CYAN]] TestExpr[[RESET]] [[Green]]'int'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]  `-[[RESET]][[BLUE]]GuardedByAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:29[[RESET]], [[Yellow]]col:43[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]    `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
-
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:26:1[[RESET]], [[Yellow]]col:5[[RESET]]> [[Yellow]]col:5[[RESET]][[CYAN]] TestExpr[[RESET]] [[Green]]'int'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[BLUE]]GuardedByAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:29[[RESET]], [[Yellow]]col:43[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:1[[RESET]], [[Yellow]]line:30:1[[RESET]]> [[Yellow]]line:28:8[[RESET]] struct[[CYAN]] Invalid[[RESET]] definition
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit struct[[CYAN]] Invalid[[RESET]]
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:29:3[[RESET]], [[Yellow]]col:42[[RESET]]> [[Yellow]]col:29[[RESET]] invalid[[CYAN]] Invalid[[RESET]] [[Green]]'void (int)'[[RESET]]
+//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:37[[RESET]], [[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]col:42[[RESET]] invalid [[Green]]'int'[[RESET]]
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[BLUE]]NoInlineAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:18[[RESET]]>
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit used[[CYAN]] Invalid[[RESET]] [[Green]]'void (void)'[[RESET]] inline noexcept-unevaluated 0x{{[0-9a-fA-F]*}}
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]>
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit[[CYAN]] Invalid[[RESET]] [[Green]]'void (const struct Invalid &)'[[RESET]] inline noexcept-unevaluated 0x{{[0-9a-fA-F]*}}
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] [[Green]]'const struct Invalid &'[[RESET]]
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit[[CYAN]] Invalid[[RESET]] [[Green]]'void (struct Invalid &&)'[[RESET]] inline noexcept-unevaluated 0x{{[0-9a-fA-F]*}}
+//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] [[Green]]'struct Invalid &&'[[RESET]]
+//CHECK: {{^}}[[Blue]]`-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:30:3[[RESET]]> [[Yellow]]col:3[[RESET]][[CYAN]] Invalid[[RESET]] [[Green]]'struct Invalid':'struct Invalid'[[RESET]]
+//CHECK: {{^}}[[Blue]]  `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'struct Invalid':'struct Invalid'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]]
diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp
index 8f20c46..b41e4ee 100644
--- a/test/Misc/ast-dump-decl.cpp
+++ b/test/Misc/ast-dump-decl.cpp
@@ -133,6 +133,31 @@
 // CHECK:      CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void (void) noexcept'
 // CHECK-NEXT:   CompoundStmt
 
+// Test that the range of a defaulted members is computed correctly.
+// FIXME: This should include the "= default".
+class TestMemberRanges {
+public:
+  TestMemberRanges() = default;
+  TestMemberRanges(const TestMemberRanges &Other) = default;
+  TestMemberRanges(TestMemberRanges &&Other) = default;
+  ~TestMemberRanges() = default;
+  TestMemberRanges &operator=(const TestMemberRanges &Other) = default;
+  TestMemberRanges &operator=(TestMemberRanges &&Other) = default;
+};
+void SomeFunction() {
+  TestMemberRanges A;
+  TestMemberRanges B(A);
+  B = A;
+  A = static_cast<TestMemberRanges &&>(B);
+  TestMemberRanges C(static_cast<TestMemberRanges &&>(A));
+}
+// CHECK:      CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:20>
+// CHECK:      CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:49>
+// CHECK:      CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:44>
+// CHECK:      CXXDestructorDecl{{.*}} <line:{{.*}}:3, col:21>
+// CHECK:      CXXMethodDecl{{.*}} <line:{{.*}}:3, col:60>
+// CHECK:      CXXMethodDecl{{.*}} <line:{{.*}}:3, col:55>
+
 class TestCXXConversionDecl {
   operator int() { return 0; }
 };
diff --git a/test/Misc/ast-print-pragmas-xfail.cpp b/test/Misc/ast-print-pragmas-xfail.cpp
new file mode 100644
index 0000000..994e1fd
--- /dev/null
+++ b/test/Misc/ast-print-pragmas-xfail.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -ast-print -o - | FileCheck %s
+
+// FIXME: Test fails because attribute order is reversed by ParsedAttributes.
+// XFAIL: *
+
+void run1(int *List, int Length) {
+  int i = 0;
+// CEHCK: #pragma loop vectorize(4)
+// CHECK-NEXT: #pragma loop interleave(8)
+// CHECK-NEXT: #pragma loop vectorize(enable)
+// CHECK-NEXT: #pragma loop interleave(enable)
+#pragma loop vectorize(4)
+#pragma loop interleave(8)
+#pragma loop vectorize(enable)
+#pragma loop interleave(enable)
+// CHECK-NEXT: while (i < Length)
+  while (i < Length) {
+    List[i] = i;
+    i++;
+  }
+}
diff --git a/test/Misc/ast-print-pragmas.cpp b/test/Misc/ast-print-pragmas.cpp
new file mode 100644
index 0000000..25421fc
--- /dev/null
+++ b/test/Misc/ast-print-pragmas.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s
+
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// reversed. The checks are consequently in the reverse order below.
+
+// CHECK: #pragma clang loop interleave_count(8)
+// CHECK-NEXT: #pragma clang loop vectorize_width(4)
+
+void test(int *List, int Length) {
+  int i = 0;
+#pragma clang loop vectorize_width(4)
+#pragma clang loop interleave_count(8)
+// CHECK-NEXT: while (i < Length)
+  while (i < Length) {
+    List[i] = i * 2;
+    i++;
+  }
+
+// CHECK: #pragma clang loop interleave(disable)
+// CHECK-NEXT: #pragma clang loop vectorize(enable)
+
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave(disable)
+// CHECK-NEXT: while (i - 1 < Length)
+  while (i - 1 < Length) {
+    List[i] = i * 2;
+    i++;
+  }
+
+// CHECK: #pragma clang loop interleave(enable)
+// CHECK-NEXT: #pragma clang loop vectorize(disable)
+
+#pragma clang loop vectorize(disable)
+#pragma clang loop interleave(enable)
+// CHECK-NEXT: while (i - 2 < Length)
+  while (i - 2 < Length) {
+    List[i] = i * 2;
+    i++;
+  }
+}
diff --git a/test/Misc/backend-stack-frame-diagnostics-fallback.cpp b/test/Misc/backend-stack-frame-diagnostics-fallback.cpp
new file mode 100644
index 0000000..8ae8c55
--- /dev/null
+++ b/test/Misc/backend-stack-frame-diagnostics-fallback.cpp
@@ -0,0 +1,18 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -mllvm -warn-stack-size=0 -emit-codegen-only -triple=i386-apple-darwin 2>&1 | FileCheck %s
+
+// TODO: Emit rich diagnostics for thunks and move this into the appropriate test file.
+// Until then, test that we fall back and display the LLVM backend diagnostic.
+namespace frameSizeThunkWarning {
+  struct A {
+    virtual void f();
+  };
+
+  struct B : virtual A {
+    virtual void f();
+  };
+
+  // CHECK: warning: stack frame size of {{[0-9]+}} bytes in function 'frameSizeThunkWarning::B::f'
+  // CHECK: warning: stack size limit exceeded ({{[0-9]+}}) in {{[^ ]+}}
+  void B::f() { }
+}
diff --git a/test/Misc/backend-stack-frame-diagnostics.cpp b/test/Misc/backend-stack-frame-diagnostics.cpp
new file mode 100644
index 0000000..1d865e7
--- /dev/null
+++ b/test/Misc/backend-stack-frame-diagnostics.cpp
@@ -0,0 +1,85 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -target i386-apple-darwin -std=c++11 -fblocks -Wframe-larger-than=70 -Xclang -verify -o /dev/null -c %s
+// RUN: %clang -target i386-apple-darwin -std=c++11 -fblocks -Wframe-larger-than=70 -Xclang -verify -o /dev/null -c %s -DIS_SYSHEADER
+
+// Test that:
+//  * The driver passes the option through to the backend.
+//  * The frontend diagnostic handler 'demangles' and resolves the correct function definition.
+
+// Test that link invocations don't emit an "argument unused during compilation" diagnostic.
+// RUN: touch %t.o
+// RUN: %clang -Werror -Wframe-larger-than=0 %t.o -###  2>&1 | not grep ' error: '
+
+// TODO: Support rich backend diagnostics for Objective-C methods.
+
+// Backend diagnostics aren't suppressed in system headers because such results
+// are significant and actionable.
+#ifdef IS_HEADER
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+#endif
+
+extern void doIt(char *);
+
+void frameSizeWarning(int, int) {}
+
+void frameSizeWarning();
+
+void frameSizeWarning() { // expected-warning-re {{stack frame size of {{[0-9]+}} bytes in function 'frameSizeWarning'}}
+  char buffer[80];
+  doIt(buffer);
+}
+
+void frameSizeWarning();
+
+void frameSizeWarning(int) {}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+void frameSizeWarningIgnored() {
+  char buffer[80];
+  doIt(buffer);
+}
+#pragma GCC diagnostic pop
+
+#pragma GCC diagnostic push
+#ifndef IS_SYSHEADER
+// expected-warning@+2 {{unknown warning group '-Wframe-larger-than'}}
+#endif
+#pragma GCC diagnostic ignored "-Wframe-larger-than"
+#pragma GCC diagnostic pop
+
+void frameSizeLocalClassWarning() {
+  struct S {
+    S() { // expected-warning-re {{stack frame size of {{[0-9]+}} bytes in function 'frameSizeLocalClassWarning()::S::S'}}
+      char buffer[80];
+      doIt(buffer);
+    }
+  };
+  S();
+}
+
+void frameSizeLambdaWarning() {
+  auto fn =
+      []() { // expected-warning-re {{stack frame size of {{[0-9]+}} bytes in lambda expression}}
+    char buffer[80];
+    doIt(buffer);
+  };
+  fn();
+}
+
+void frameSizeBlocksWarning() {
+  auto fn =
+      ^() { // expected-warning-re {{stack frame size of {{[0-9]+}} bytes in block literal}}
+    char buffer[80];
+    doIt(buffer);
+  };
+  fn();
+}
+
+#else
+
+#define IS_HEADER
+#include __FILE__
+#endif
diff --git a/test/Misc/diag-mapping2.c b/test/Misc/diag-mapping2.c
index c4ade07..672d054 100644
--- a/test/Misc/diag-mapping2.c
+++ b/test/Misc/diag-mapping2.c
@@ -1,22 +1,21 @@
 // This should warn by default.
-// RUN: %clang_cc1 %s 2>&1 | grep "warning:"
+// RUN: %clang_cc1 %s 2>&1 | grep "warning: foo"
 
 // This should not emit anything.
 // RUN: %clang_cc1 %s -w 2>&1 | not grep diagnostic
 // RUN: %clang_cc1 %s -Wno-#warnings 2>&1 | not grep diagnostic
 
 // -Werror can map all warnings to error.
-// RUN: not %clang_cc1 %s -Werror 2>&1 | grep "error:"
+// RUN: not %clang_cc1 %s -Werror 2>&1 | grep "error: foo"
 
 // -Werror can map this one warning to error.
-// RUN: not %clang_cc1 %s -Werror=#warnings 2>&1 | grep "error:"
+// RUN: not %clang_cc1 %s -Werror=#warnings 2>&1 | grep "error: foo"
 
 // -Wno-error= overrides -Werror.  rdar://3158301
-// RUN: %clang_cc1 %s -Werror -Wno-error=#warnings 2>&1 | grep "warning:"
+// RUN: %clang_cc1 %s -Werror -Wno-error=#warnings 2>&1 | grep "warning: foo"
 
 // -Wno-error overrides -Werror.  PR4715
-// RUN: %clang_cc1 %s -Werror -Wno-error 2>&1 | grep "warning:"
+// RUN: %clang_cc1 %s -Werror -Wno-error 2>&1 | grep "warning: foo"
 
 #warning foo
 
-
diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp
index 4680707..c43ed26 100644
--- a/test/Misc/diag-template-diffing.cpp
+++ b/test/Misc/diag-template-diffing.cpp
@@ -1068,6 +1068,43 @@
 }
 }
 
+namespace PR15677 {
+template <bool>
+struct A{};
+
+template <typename T>
+using B = A<T::value>;
+
+template <typename T>
+using B = A<!T::value>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<!T::value>' vs 'A<T::value>')
+
+template <int>
+struct C{};
+
+template <typename T>
+using D = C<T::value>;
+
+template <typename T>
+using D = C<T::value + 1>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C<T::value + 1>' vs 'C<T::value>')
+
+template <typename T>
+using E = C<T::value>;
+
+template <typename T>
+using E = C<42>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C<42>' vs 'C<T::value>')
+
+template <typename T>
+using F = C<T::value>;
+
+template <typename T>
+using F = C<21 + 21>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C<21 + 21 aka 42>' vs 'C<T::value>')
+}
+}
+
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index 5a45172..b46e4fe 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -18,7 +18,7 @@
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (106):
+CHECK: Warnings without flags (105):
 CHECK-NEXT:   ext_delete_void_ptr_operand
 CHECK-NEXT:   ext_expected_semi_decl_list
 CHECK-NEXT:   ext_explicit_specialization_storage_class
@@ -114,7 +114,6 @@
 CHECK-NEXT:   warn_register_objc_catch_parm
 CHECK-NEXT:   warn_related_result_type_compatibility_class
 CHECK-NEXT:   warn_related_result_type_compatibility_protocol
-CHECK-NEXT:   warn_static_non_static
 CHECK-NEXT:   warn_template_export_unsupported
 CHECK-NEXT:   warn_template_spec_extra_headers
 CHECK-NEXT:   warn_tentative_incomplete_array
diff --git a/test/Misc/win32-macho.c b/test/Misc/win32-macho.c
new file mode 100644
index 0000000..517bde9
--- /dev/null
+++ b/test/Misc/win32-macho.c
@@ -0,0 +1,2 @@
+// Check that basic use of win32-macho targets works.
+// RUN: %clang -fsyntax-only -target x86_64-pc-win32-macho %s
diff --git a/test/Modules/Inputs/cxx-decls-imported.h b/test/Modules/Inputs/cxx-decls-imported.h
index 5c7f6fc..38cc00d 100644
--- a/test/Modules/Inputs/cxx-decls-imported.h
+++ b/test/Modules/Inputs/cxx-decls-imported.h
@@ -20,3 +20,6 @@
 static_assert(!__has_trivial_constructor(HasNontrivialDefaultConstructor), "");
 
 void *operator new[](__SIZE_TYPE__);
+
+extern int mergeUsedFlag;
+inline int getMergeUsedFlag() { return mergeUsedFlag; }
diff --git a/test/Modules/Inputs/cxx-decls-merged.h b/test/Modules/Inputs/cxx-decls-merged.h
new file mode 100644
index 0000000..ccc3b01
--- /dev/null
+++ b/test/Modules/Inputs/cxx-decls-merged.h
@@ -0,0 +1 @@
+extern int mergeUsedFlag;
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index a85145f..fea1201 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -238,6 +238,10 @@
   }
 }
 
+module cxx_decls_merged {
+  header "cxx-decls-merged.h"
+}
+
 module config {
   header "config.h"
   config_macros [exhaustive] WANT_FOO, WANT_BAR
diff --git a/test/Modules/Inputs/templates-left.h b/test/Modules/Inputs/templates-left.h
index ae9d8bd..2bd79be 100644
--- a/test/Modules/Inputs/templates-left.h
+++ b/test/Modules/Inputs/templates-left.h
@@ -56,3 +56,7 @@
 template<> struct DelayUpdates<int>;
 template<typename T> struct DelayUpdates<T*>;
 template<typename T> void testDelayUpdates(DelayUpdates<T> *p = 0) {}
+
+void outOfLineInlineUseLeftF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f);
+void outOfLineInlineUseLeftG(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::g);
+void outOfLineInlineUseLeftH(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::h);
diff --git a/test/Modules/Inputs/templates-right.h b/test/Modules/Inputs/templates-right.h
index c8056d6..5907cbc 100644
--- a/test/Modules/Inputs/templates-right.h
+++ b/test/Modules/Inputs/templates-right.h
@@ -39,3 +39,7 @@
 }
 
 template<typename T> struct MergePatternDecl;
+
+void outOfLineInlineUseRightF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f);
+void outOfLineInlineUseRightG(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::g);
+void outOfLineInlineUseRightH(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::h);
diff --git a/test/Modules/Inputs/templates-top.h b/test/Modules/Inputs/templates-top.h
index 168155b..1216266 100644
--- a/test/Modules/Inputs/templates-top.h
+++ b/test/Modules/Inputs/templates-top.h
@@ -31,3 +31,12 @@
 };
 
 template<typename> struct DelayUpdates {};
+
+template<typename T> struct OutOfLineInline {
+  void f();
+  void g();
+  void h();
+};
+template<typename T> inline void OutOfLineInline<T>::f() {}
+template<typename T> inline void OutOfLineInline<T>::g() {}
+template<typename T> inline void OutOfLineInline<T>::h() {}
diff --git a/test/Modules/autolink.m b/test/Modules/autolink.m
index 883a2f5..47eda3f 100644
--- a/test/Modules/autolink.m
+++ b/test/Modules/autolink.m
@@ -36,8 +36,8 @@
 
 // NOTE: "autolink_sub" is intentionally not linked.
 
-// CHECK: !llvm.module.flags = !{!0, !1, !2, !3, !4}
-// CHECK: !4 = metadata !{i32 6, metadata !"Linker Options", metadata ![[AUTOLINK_OPTIONS:[0-9]+]]}
+// CHECK: !llvm.module.flags = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[AUTOLINK_OPTIONS:[0-9]+]]}
 // CHECK: ![[AUTOLINK_OPTIONS]] = metadata !{metadata ![[AUTOLINK_PCH:[0-9]+]], metadata ![[AUTOLINK_FRAMEWORK:[0-9]+]], metadata ![[AUTOLINK:[0-9]+]], metadata ![[DEPENDSONMODULE:[0-9]+]], metadata ![[MODULE:[0-9]+]], metadata ![[NOUMBRELLA:[0-9]+]]}
 // CHECK: ![[AUTOLINK_PCH]] = metadata !{metadata !"{{(-l|/DEFAULTLIB:)}}autolink_from_pch{{(\.lib)?}}"}
 // CHECK: ![[AUTOLINK_FRAMEWORK]] = metadata !{metadata !"-framework", metadata !"autolink_framework"}
diff --git a/test/Modules/compiler_builtins_arm.m b/test/Modules/compiler_builtins_arm.m
index d15437c..5da6a12 100644
--- a/test/Modules/compiler_builtins_arm.m
+++ b/test/Modules/compiler_builtins_arm.m
@@ -1,6 +1,5 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fsyntax-only -triple thumbv7-none-linux-gnueabihf -target-abi aapcs -target-cpu cortex-a8 -mfloat-abi hard -std=c99 -fmodules -fmodules-cache-path=%t -D__need_wint_t %s -verify
 // expected-no-diagnostics
-// REQUIRES: arm-registered-target
 
 @import _Builtin_intrinsics.arm.neon;
diff --git a/test/Modules/cxx-decls.cpp b/test/Modules/cxx-decls.cpp
index 49ba834..5498b47 100644
--- a/test/Modules/cxx-decls.cpp
+++ b/test/Modules/cxx-decls.cpp
@@ -1,5 +1,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -ast-dump -ast-dump-filter merge -std=c++11 | FileCheck %s
 
 // expected-no-diagnostics
 
@@ -26,3 +27,10 @@
 static_assert(!__has_trivial_constructor(HasNontrivialDefaultConstructor), "");
 
 void use_implicit_new_again() { operator new[](3); }
+
+int importMergeUsedFlag = getMergeUsedFlag();
+
+@import cxx_decls_merged;
+
+// CHECK: VarDecl [[mergeUsedFlag:0x[0-9a-f]*]] {{.*}} in cxx_decls.imported used mergeUsedFlag
+// CHECK: VarDecl {{0x[0-9a-f]*}} prev [[mergeUsedFlag]] {{.*}} in cxx_decls_merged used mergeUsedFlag
diff --git a/test/Modules/cxx-irgen.cpp b/test/Modules/cxx-irgen.cpp
index 7c680f8..4c61a3a 100644
--- a/test/Modules/cxx-irgen.cpp
+++ b/test/Modules/cxx-irgen.cpp
@@ -4,7 +4,7 @@
 
 @import cxx_irgen_top;
 
-// CHECK-DAG: call i32 @_ZN8CtorInitIiE1fEv(
+// CHECK-DAG: call {{[a-z]*[ ]?i32}} @_ZN8CtorInitIiE1fEv(
 CtorInit<int> x;
 
 @import cxx_irgen_left;
diff --git a/test/Modules/dependency-dump-dependent-module.m b/test/Modules/dependency-dump-dependent-module.m
new file mode 100644
index 0000000..3b04435
--- /dev/null
+++ b/test/Modules/dependency-dump-dependent-module.m
@@ -0,0 +1,22 @@
+// When a module depends on another, check that we dump the dependency header
+// files for both.
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -module-dependency-dir %t/vfs -F %S/Inputs -I %S/Inputs -verify %s
+// expected-no-diagnostics
+
+// RUN: FileCheck %s -check-prefix=VFS < %t/vfs/vfs.yaml
+// VFS: 'name': "AlsoDependsOnModule.h"
+// VFS: 'name': "SubFramework.h"
+// VFS: 'name': "Treasure.h"
+// VFS: 'name': "Module.h"
+// VFS: 'name': "Sub.h"
+// VFS: 'name': "Sub2.h"
+
+@import AlsoDependsOnModule;
+
+// FIXME: This fails on win32 due to ERROR_FILENAME_EXCED_RANGE
+// if the working directory is too deep.
+// We should make Win32/Path.inc capable of long pathnames with '\\?\'.
+// For now, this is suppressed on win32.
+// REQUIRES: shell
diff --git a/test/Modules/dependency-dump.m b/test/Modules/dependency-dump.m
new file mode 100644
index 0000000..630af49
--- /dev/null
+++ b/test/Modules/dependency-dump.m
@@ -0,0 +1,15 @@
+// Check that we can dump all of the headers a module depends on, and a VFS map
+// for the same.
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -module-dependency-dir %t/vfs -F %S/Inputs -I %S/Inputs -verify %s
+// expected-no-diagnostics
+
+// RUN: FileCheck %s -check-prefix=VFS -input-file %t/vfs/vfs.yaml
+// VFS: 'name': "SubFramework.h"
+// VFS: 'name': "Treasure.h"
+// VFS: 'name': "Module.h"
+// VFS: 'name': "Sub.h"
+// VFS: 'name': "Sub2.h"
+
+@import Module;
diff --git a/test/Modules/templates.mm b/test/Modules/templates.mm
index ebd55df..645e171 100644
--- a/test/Modules/templates.mm
+++ b/test/Modules/templates.mm
@@ -4,6 +4,12 @@
 // expected-no-diagnostics
 
 @import templates_left;
+
+void testInlineRedeclEarly() {
+  // instantiate definition now, we'll add another declaration in _right.
+  OutOfLineInline<int>().h();
+}
+
 @import templates_right;
 
 // CHECK: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8,
@@ -39,6 +45,14 @@
   redeclDefinitionEmit();
 }
 
+void testInlineRedecl() {
+  outOfLineInlineUseLeftF();
+  outOfLineInlineUseRightG();
+
+  outOfLineInlineUseRightF();
+  outOfLineInlineUseLeftG();
+}
+
 // CHECK-NOT: @_ZN21ExplicitInstantiationILb0ELb0EE1fEv(
 // CHECK: declare {{.*}}@_ZN21ExplicitInstantiationILb1ELb0EE1fEv(
 // CHECK: define {{.*}}@_ZN21ExplicitInstantiationILb1ELb1EE1fEv(
@@ -66,9 +80,9 @@
   // CHECK: call {{.*}}memcpy{{.*}}(i8* %{{.*}}, i8* bitcast ({{.*}}* @_ZZ15testMixedStructvE1r to i8*), i64 16,
   ListInt_right r{0, 2};
 
-  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* %[[l]])
+  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* nonnull %[[l]])
   useListInt(l);
-  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* %[[r]])
+  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* nonnull %[[r]])
   useListInt(r);
 
   // CHECK: load i32* bitcast (i8* getelementptr inbounds (i8* bitcast ({{.*}}* @list_left to i8*), i64 8) to i32*)
diff --git a/test/OpenMP/for_ast_print.cpp b/test/OpenMP/for_ast_print.cpp
new file mode 100644
index 0000000..8802237
--- /dev/null
+++ b/test/OpenMP/for_ast_print.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+#pragma omp for schedule(dynamic)
+  // CHECK-NEXT: #pragma omp for schedule(dynamic)
+  for (int i = 0; i < 2; ++i)
+    a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp parallel
+#pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered nowait
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      for (int j = 0; j < 10; ++j)
+        for (int j = 0; j < 10; ++j)
+          for (int j = 0; j < 10; ++j)
+            foo();
+  // CHECK-NEXT: #pragma omp parallel
+  // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered nowait
+  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: foo();
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp for schedule(guided, argc)
+  // CHECK-NEXT: #pragma omp for schedule(guided, argc)
+  for (int i = 0; i < 2; ++i)
+    a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp parallel
+#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered nowait
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+  // CHECK-NEXT: #pragma omp parallel
+  // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered nowait
+  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: foo();
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/for_collapse_messages.cpp b/test/OpenMP/for_collapse_messages.cpp
new file mode 100644
index 0000000..9e14234
--- /dev/null
+++ b/test/OpenMP/for_collapse_messages.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+  #pragma omp for collapse // expected-error {{expected '(' after 'collapse'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse () // expected-error {{expected expression}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 2 {{expression is not an integral constant expression}}
+  // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+  #pragma omp for collapse (argc 
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp for collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}}
+  // expected-error@+3 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
+  // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}}
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (S) // expected-error {{'S' does not refer to a value}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp for collapse // expected-error {{expected '(' after 'collapse'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for collapse () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+  #pragma omp for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}  expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+  #pragma omp for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{expression is not an integral constant expression}}
+  // expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5) 
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for collapse (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+1 {{expression is not an integral constant expression}}
+  #pragma omp for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{statement after '#pragma omp for' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo();
+  #pragma omp for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/for_firstprivate_messages.cpp b/test/OpenMP/for_firstprivate_messages.cpp
new file mode 100644
index 0000000..f1d21b8
--- /dev/null
+++ b/test/OpenMP/for_firstprivate_messages.cpp
@@ -0,0 +1,293 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                      // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+#pragma omp for firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel private(i) // expected-note {{defined as private}}
+#pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp for firstprivate(i)       // expected-error {{firstprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(ba) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(ca) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(da) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp parallel
+#pragma omp for firstprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(S2::S2s) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(S2::S2sc) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp for'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(m) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i)    // expected-error {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}}
+    foo();
+#pragma omp parallel shared(xa)
+#pragma omp for firstprivate(xa) // OK: may be firstprivate
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                      // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+#pragma omp for firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel private(i) // expected-note {{defined as private}}
+#pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp for firstprivate(i)       // expected-error {{firstprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/for_lastprivate_messages.cpp b/test/OpenMP/for_lastprivate_messages.cpp
new file mode 100644
index 0000000..a3a1c4b
--- /dev/null
+++ b/test/OpenMP/for_lastprivate_messages.cpp
@@ -0,0 +1,266 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note 2 {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note 3 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  I g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                     // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+#pragma omp for lastprivate(i) // expected-error {{lastprivate variable must be shared}}
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note 2 {{'m' defined here}}
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(ba)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp parallel
+#pragma omp for lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp for'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(i)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel private(xa) // expected-note {{defined as private}}
+#pragma omp for lastprivate(xa)  // expected-error {{lastprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel reduction(+ : xa) // expected-note {{defined as reduction}}
+#pragma omp for lastprivate(xa)        // expected-error {{lastprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp
new file mode 100644
index 0000000..deed0ec
--- /dev/null
+++ b/test/OpenMP/for_loop_messages.cpp
@@ -0,0 +1,680 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+class S {
+  int a;
+  S() : a(0) {}
+
+public:
+  S(int v) : a(v) {}
+  S(const S &s) : a(s.a) {}
+};
+
+static int sii;
+#pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+
+int test_iteration_spaces() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  int ii, jj, kk;
+  float fii;
+  double dii;
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; i += 1) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+#pragma omp for
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+#pragma omp for
+  for (char i = 0; i < 10; i += '\1') {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+#pragma omp for
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+#pragma omp for
+  for (long long i = 0; i < 10; i += 1.5) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+#pragma omp for
+  for (long long i = 0; i < 'z'; i += 1u) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp for
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp for
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (ii + 1; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (c[ii] = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// Ok to skip parenthesises.
+#pragma omp for
+  for (((ii)) = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp for
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+#pragma omp for
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp for
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp for
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp for
+  for (int i = 0;; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// Ok.
+#pragma omp for
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+#pragma omp parallel
+// Ok.
+#pragma omp for
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+#pragma omp parallel
+// Ok.
+#pragma omp for
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ++++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// Ok but undefined behavior (in general, cannot check that incr
+// is really loop-invariant).
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// Ok - step was converted to integer type.
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-warning@+3 {{relational comparison result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii<10; jj> kk + 2)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; (ii) < 10; ii -= 25)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; (ii < 10); ii -= 0)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; ii > 10; (ii += 0))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for ((ii = 0); ii > 10; (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; (ii < 10); (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+2  {{defined as firstprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}}
+#pragma omp for firstprivate(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+3 {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}}
+// expected-note@+2  {{defined as linear}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be linear, predetermined as private}}
+#pragma omp for linear(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+#pragma omp for private(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+#pragma omp for lastprivate(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+  {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be threadprivate or thread local, predetermined as private}}
+#pragma omp for
+    for (sii = 0; sii < 10; sii += 1)
+      c[sii] = a[sii];
+  }
+
+#pragma omp parallel
+// expected-error@+2 {{statement after '#pragma omp for' must be a for loop}}
+#pragma omp for
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int(*lb)[4] = nullptr;
+#pragma omp parallel
+#pragma omp for
+  for (int(*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (int a{0}; a < 10; ++a) {
+  }
+
+  return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag {};
+template <class Iter>
+struct iterator_traits {
+  typedef typename Iter::difference_type difference_type;
+  typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+public:
+  Iter0() {}
+  Iter0(const Iter0 &) {}
+  Iter0 operator++() { return *this; }
+  Iter0 operator--() { return *this; }
+  bool operator<(Iter0 a) { return true; }
+};
+int operator-(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+public:
+  Iter1(float f = 0.0f, double d = 0.0) {}
+  Iter1(const Iter1 &) {}
+  Iter1 operator++() { return *this; }
+  Iter1 operator--() { return *this; }
+  bool operator<(Iter1 a) { return true; }
+  bool operator>=(Iter1 a) { return false; }
+};
+class GoodIter {
+public:
+  GoodIter() {}
+  GoodIter(const GoodIter &) {}
+  GoodIter(int fst, int snd) {}
+  GoodIter &operator=(const GoodIter &that) { return *this; }
+  GoodIter &operator=(const Iter0 &that) { return *this; }
+  GoodIter &operator+=(int x) { return *this; }
+  explicit GoodIter(void *) {}
+  GoodIter operator++() { return *this; }
+  GoodIter operator--() { return *this; }
+  bool operator!() { return true; }
+  bool operator<(GoodIter a) { return true; }
+  bool operator<=(GoodIter a) { return true; }
+  bool operator>=(GoodIter a) { return false; }
+  typedef int difference_type;
+  typedef std::random_access_iterator_tag iterator_category;
+};
+int operator-(GoodIter a, GoodIter b) { return 0; }
+GoodIter operator-(GoodIter a) { return a; }
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+#pragma omp parallel
+#pragma omp for
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp for
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+#pragma omp parallel
+#pragma omp for
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (GoodIter I(1, 2); I < end; ++I)
+    ++I;
+#pragma omp parallel
+#pragma omp for
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+#pragma omp parallel
+#pragma omp for
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (++begin; begin < end; ++begin)
+    ++begin;
+#pragma omp parallel
+#pragma omp for
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+#pragma omp parallel
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+#pragma omp parallel
+#pragma omp for
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+#pragma omp parallel
+// Initializer is constructor without params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+#pragma omp parallel
+#pragma omp for
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+#pragma omp parallel
+// Initializer is constructor with all default params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (Iter1 I; I < end1; ++I) {
+  }
+  return 0;
+}
+
+template <typename IT, int ST>
+class TC {
+public:
+  int dotest_lt(IT begin, IT end) {
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+    for (IT I = begin; I < end; I = I + ST) {
+      ++I;
+    }
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+    for (IT I = begin; I <= end; I += ST) {
+      ++I;
+    }
+#pragma omp parallel
+#pragma omp for
+    for (IT I = begin; I < end; ++I) {
+      ++I;
+    }
+  }
+
+  static IT step() {
+    return IT(ST);
+  }
+};
+template <typename IT, int ST = 0>
+int dotest_gt(IT begin, IT end) {
+#pragma omp parallel
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+#pragma omp parallel
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+#pragma omp parallel
+#pragma omp for
+  for (IT I = begin; I < end; I += TC<int, ST>::step()) {
+    ++I;
+  }
+}
+
+void test_with_template() {
+  GoodIter begin, end;
+  TC<GoodIter, 100> t1;
+  TC<GoodIter, -100> t2;
+  t1.dotest_lt(begin, end);
+  t2.dotest_lt(begin, end);         // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+  dotest_gt(begin, end);            // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+  dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    for (int j = 0; j < 10; ++j) {
+      if (a[i] > b[j])
+        break; // OK in nested loop
+    }
+    switch (i) {
+    case 1:
+      b[i]++;
+      break;
+    default:
+      break;
+    }
+    if (c[i] > 10)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+    if (c[i] > 11)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+  }
+
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; i++) {
+    for (int j = 0; j < 10; j++) {
+      c[i] = a[i] + b[i];
+      if (c[i] > 10) {
+        if (c[i] < 20) {
+          break; // OK
+        }
+      }
+    }
+  }
+}
+
+void test_loop_eh() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    try {
+      for (int j = 0; j < 10; ++j) {
+        if (a[i] > b[j])
+          throw a[i];
+      }
+      throw a[i];
+    } catch (float f) {
+      if (f > 0.1)
+        throw a[i];
+      return; // expected-error {{cannot return from OpenMP region}}
+    }
+    switch (i) {
+    case 1:
+      b[i]++;
+      break;
+    default:
+      break;
+    }
+    for (int j = 0; j < 10; j++) {
+      if (c[i] > 10)
+        throw c[i];
+    }
+  }
+  if (c[9] > 10)
+    throw c[9]; // OK
+
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
+void test_loop_firstprivate_lastprivate() {
+  S s(4);
+#pragma omp parallel
+#pragma omp for lastprivate(s) firstprivate(s)
+  for (int i = 0; i < 16; ++i)
+    ;
+}
diff --git a/test/OpenMP/for_misc_messages.c b/test/OpenMP/for_misc_messages.c
new file mode 100644
index 0000000..854898c
--- /dev/null
+++ b/test/OpenMP/for_misc_messages.c
@@ -0,0 +1,363 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp for'}}
+#pragma omp for
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp for'}}
+#pragma omp for foo
+
+void test_no_clause() {
+  int i;
+#pragma omp for
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{statement after '#pragma omp for' must be a for loop}}
+#pragma omp for
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel
+#pragma omp for
+  for (i = 0; i < 16; ++i) {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+}
+
+void test_invalid_clause() {
+  int i;
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for foo bar
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for;
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for linear(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for, private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+extern int foo();
+
+void test_collapse() {
+  int i;
+#pragma omp parallel
+// expected-error@+1 {{expected '('}}
+#pragma omp for collapse
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp for collapse(
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for collapse()
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp for collapse(,
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}  expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp for collapse(, )
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp for' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp for collapse 4)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4,
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4, )
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4, , 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+#pragma omp for collapse(4)
+  for (int i1 = 0; i1 < 16; ++i1)
+    for (int i2 = 0; i2 < 16; ++i2)
+      for (int i3 = 0; i3 < 16; ++i3)
+        for (int i4 = 0; i4 < 16; ++i4)
+          foo();
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4, 8)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp for collapse(2.5)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp for collapse(foo())
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp for collapse(-5)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp for collapse(0)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp for collapse(5 - 5)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_private() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp for private(
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for private(,
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for private(, )
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for private()
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for private(int)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp for private(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp for private(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for private(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for private(x, y, z)
+  for (i = 0; i < 16; ++i) {
+    x = y * i + z;
+  }
+}
+
+void test_lastprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp for lastprivate(
+  for (i = 0; i < 16; ++i)
+    ;
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for lastprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for lastprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for lastprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for lastprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp for lastprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp for lastprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for lastprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for lastprivate(x, y, z)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_firstprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp for firstprivate(
+  for (i = 0; i < 16; ++i)
+    ;
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for firstprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for firstprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for firstprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for firstprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp for firstprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp for lastprivate(x) firstprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for lastprivate(x, y) firstprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for lastprivate(x, y, z) firstprivate(x, y, z)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_loop_messages() {
+  float a[100], b[100], c[100];
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp for
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/for_private_messages.cpp b/test/OpenMP/for_private_messages.cpp
new file mode 100644
index 0000000..f7a4979
--- /dev/null
+++ b/test/OpenMP/for_private_messages.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;           // expected-note {{'j' defined here}}
+#pragma omp for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(e, g)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp for private(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;           // expected-note {{'j' defined here}}
+#pragma omp for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int i;
+#pragma omp for private(i)
+    for (int k = 0; k < argc; ++k)
+      ++k;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+
+  return 0;
+}
+
diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp
new file mode 100644
index 0000000..62fee52
--- /dev/null
+++ b/test/OpenMP/for_reduction_messages.cpp
@@ -0,0 +1,350 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                // expected-note 4 {{'j' defined here}}
+  S3 &p = k;               // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];       // expected-note 2 {{'q' defined here}}
+  T fl;                    // expected-note {{'fl' defined here}}
+#pragma omp parallel
+#pragma omp for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)  // expected-note 2 {{defined as private}}
+#pragma omp for reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl) // expected-note 2 {{defined as reduction}}
+#pragma omp for reduction(+ : fl)      // expected-error 2 {{reduction variable must be shared}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;           // expected-note 2 {{'j' defined here}}
+  S3 &p = k;            // expected-note 2 {{'p' defined here}}
+  const int &r = da[i]; // expected-note {{'r' defined here}}
+  int &q = qa[i];       // expected-note {{'q' defined here}}
+  float fl;             // expected-note {{'fl' defined here}}
+#pragma omp parallel
+#pragma omp for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(max : argv[1]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)  // expected-note {{defined as private}}
+#pragma omp for reduction(+ : fl) // expected-error {{reduction variable must be shared}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl) // expected-note {{defined as reduction}}
+#pragma omp for reduction(+ : fl)      // expected-error {{reduction variable must be shared}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/for_schedule_messages.cpp b/test/OpenMP/for_schedule_messages.cpp
new file mode 100644
index 0000000..be4ff4f
--- /dev/null
+++ b/test/OpenMP/for_schedule_messages.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  #pragma omp for schedule // expected-error {{expected '(' after 'schedule'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (auto,  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (runtime, 3)  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp for schedule (guided argc
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp for schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (guided, (ST > 0) ? 1 + ST : 2)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'schedule' clause}}
+  // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (dynamic, 1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp for schedule // expected-error {{expected '(' after 'schedule'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (auto,  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (runtime, 3)  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (dynamic, foobool(1) > 0 ? 1 : 2)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'schedule' clause}}
+  // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{statement after '#pragma omp for' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp
new file mode 100644
index 0000000..2c58e0b
--- /dev/null
+++ b/test/OpenMP/nesting_of_regions.cpp
@@ -0,0 +1,892 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+void bar();
+
+template <class T>
+void foo() {
+// PARALLEL DIRECTIVE
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp sections
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel region}}
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp single
+  bar();
+#pragma omp parallel
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp parallel sections
+  {
+    bar();
+  }
+
+// SIMD DIRECTIVE
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+
+// FOR DIRECTIVE
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+
+// SECTIONS DIRECTIVE
+#pragma omp sections
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+
+// SECTION DIRECTIVE
+#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
+  {
+    bar();
+  }
+
+// SINGLE DIRECTIVE
+#pragma omp single
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp single
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+
+// PARALLEL FOR DIRECTIVE
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+
+// PARALLEL SECTIONS DIRECTIVE
+#pragma omp parallel sections
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+}
+
+void foo() {
+// PARALLEL DIRECTIVE
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp sections
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel region}}
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp sections
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp single
+  bar();
+#pragma omp parallel
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp parallel sections
+  {
+    bar();
+  }
+
+// SIMD DIRECTIVE
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+
+// FOR DIRECTIVE
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+
+// SECTIONS DIRECTIVE
+#pragma omp sections
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    bar();
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+
+// SECTION DIRECTIVE
+#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
+  {
+    bar();
+  }
+
+// SINGLE DIRECTIVE
+#pragma omp single
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp single
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+
+// PARALLEL FOR DIRECTIVE
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+
+// PARALLEL SECTIONS DIRECTIVE
+#pragma omp parallel sections
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+  return foo<int>();
+}
+
diff --git a/test/OpenMP/no_option.c b/test/OpenMP/no_option.c
index 4acc8d0..8a65b03 100644
--- a/test/OpenMP/no_option.c
+++ b/test/OpenMP/no_option.c
@@ -2,5 +2,5 @@
 // expected-no-diagnostics
 
 int a;
-#pragma omp threadprivate(a,b)
+#pragma omp threadprivate(a, b)
 #pragma omp parallel
diff --git a/test/OpenMP/no_option_no_warn.c b/test/OpenMP/no_option_no_warn.c
index c989991..10778c0 100644
--- a/test/OpenMP/no_option_no_warn.c
+++ b/test/OpenMP/no_option_no_warn.c
@@ -2,5 +2,5 @@
 // expected-no-diagnostics
 
 int a;
-#pragma omp threadprivate(a,b)
+#pragma omp threadprivate(a, b)
 #pragma omp parallel
diff --git a/test/OpenMP/parallel_ast_print.cpp b/test/OpenMP/parallel_ast_print.cpp
index 631d179..0415c0c 100644
--- a/test/OpenMP/parallel_ast_print.cpp
+++ b/test/OpenMP/parallel_ast_print.cpp
@@ -35,9 +35,9 @@
   S<T> s;
 #pragma omp parallel
   a=2;
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master)
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+:c) reduction(max:e)
   foo();
-#pragma omp parallel if (C) num_threads(s) proc_bind(close)
+#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f) reduction(&& : g)
   foo();
   return 0;
 }
@@ -48,9 +48,9 @@
 // CHECK-NEXT: S<int> s;
 // CHECK-NEXT: #pragma omp parallel
 // CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
 // CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close)
+// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g)
 // CHECK-NEXT: foo()
 // CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) {
 // CHECK-NEXT: long b = argc, c, d, e, f, g;
@@ -58,9 +58,9 @@
 // CHECK-NEXT: S<long> s;
 // CHECK-NEXT: #pragma omp parallel
 // CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
 // CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close)
+// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g)
 // CHECK-NEXT: foo()
 // CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
 // CHECK-NEXT: T b = argc, c, d, e, f, g;
@@ -68,9 +68,9 @@
 // CHECK-NEXT: S<T> s;
 // CHECK-NEXT: #pragma omp parallel
 // CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
 // CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close)
+// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g)
 // CHECK-NEXT: foo()
 
 enum Enum { };
@@ -86,8 +86,8 @@
 // CHECK-NEXT: #pragma omp parallel
   a=2;
 // CHECK-NEXT: a = 2;
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a) proc_bind(spread)
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a) proc_bind(spread)
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d) reduction(* : e)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d) reduction(*: e)
   foo();
 // CHECK-NEXT: foo();
   return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp
index 28505ab..d9ff5ac 100644
--- a/test/OpenMP/parallel_codegen.cpp
+++ b/test/OpenMP/parallel_codegen.cpp
@@ -34,14 +34,14 @@
   return tmain(argv);
 }
 
-// CHECK-LABEL: define i32 @main(i32 %argc, i8** %argv)
+// CHECK-LABEL: define {{[a-z]*[ ]?i32}} @main({{i32[ ]?[a-z]*}} %argc, i8** %argv)
 // CHECK:       [[AGG_CAPTURED:%.+]] = alloca %struct.anon
 // CHECK:       [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon* [[AGG_CAPTURED]], i32 0, i32 0
 // CHECK-NEXT:  store i32* {{%[a-z0-9.]+}}, i32** [[ARGC_REF]]
 // CHECK-NEXT:  [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8*
 // CHECK-NEXT:  call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @__captured_stmt to void (i32*, i32*, ...)*), i8* [[BITCAST]])
 // CHECK-NEXT:  [[ARGV:%.+]] = load i8*** {{%[a-z0-9.]+}}
-// CHECK-NEXT:  [[RET:%.+]] = call i32 [[TMAIN:@.+tmain.+]](i8** [[ARGV]])
+// CHECK-NEXT:  [[RET:%.+]] = call {{[a-z]*[ ]?i32}} [[TMAIN:@.+tmain.+]](i8** [[ARGV]])
 // CHECK-NEXT:  ret i32 [[RET]]
 // CHECK-NEXT:  }
 // CHECK-DEBUG-LABEL: define i32 @main(i32 %argc, i8** %argv)
@@ -68,7 +68,7 @@
 // CHECK-NEXT:  [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon* [[CONTEXT_PTR]], i32 0, i32 0
 // CHECK-NEXT:  [[ARGC_REF:%.+]] = load i32** [[ARGC_PTR_REF]]
 // CHECK-NEXT:  [[ARGC:%.+]] = load i32* [[ARGC_REF]]
-// CHECK-NEXT:  invoke void [[FOO:@.+foo.+]](i32 [[ARGC]])
+// CHECK-NEXT:  invoke void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]])
 // CHECK:       ret void
 // CHECK:       call void @{{.+terminate.*}}(
 // CHECK-NEXT:  unreachable
@@ -86,12 +86,12 @@
 // CHECK-DEBUG-NEXT:  unreachable
 // CHECK-DEBUG-NEXT:  }
 
-// CHECK-DAG: define linkonce_odr void [[FOO]](i32 %argc)
+// CHECK-DAG: define linkonce_odr void [[FOO]]({{i32[ ]?[a-z]*}} %argc)
 // CHECK-DAG: declare void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
 // CHECK-DEBUG-DAG: define linkonce_odr void [[FOO]](i32 %argc)
 // CHECK-DEBUG-DAG: declare void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
 
-// CHECK:       define linkonce_odr i32 [[TMAIN]](i8** %argc)
+// CHECK:       define linkonce_odr {{[a-z]*[ ]?i32}} [[TMAIN]](i8** %argc)
 // CHECK:       [[AGG_CAPTURED:%.+]] = alloca %struct.anon.0
 // CHECK:       [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon.0* [[AGG_CAPTURED]], i32 0, i32 0
 // CHECK-NEXT:  store i8*** {{%[a-z0-9.]+}}, i8**** [[ARGC_REF]]
diff --git a/test/OpenMP/parallel_for_ast_print.cpp b/test/OpenMP/parallel_for_ast_print.cpp
new file mode 100644
index 0000000..375664f
--- /dev/null
+++ b/test/OpenMP/parallel_for_ast_print.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, h;
+  static T a;
+// CHECK: static T a;
+  static T g;
+#pragma omp threadprivate(g)
+#pragma omp parallel for schedule(dynamic) default(none) copyin(g)
+  // CHECK: #pragma omp parallel for schedule(dynamic) default(none) copyin(g)
+  for (int i = 0; i < 2; ++i)
+    a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered if (argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      for (int j = 0; j < 10; ++j)
+        for (int j = 0; j < 10; ++j)
+          for (int j = 0; j < 10; ++j)
+            foo();
+  // CHECK-NEXT: #pragma omp parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered if(argc) num_threads(N) default(shared) shared(e) reduction(+: h)
+  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: foo();
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int b = argc, c, d, e, f, h;
+  static int a;
+// CHECK: static int a;
+  static float g;
+#pragma omp threadprivate(g)
+#pragma omp parallel for schedule(guided, argc) default(none) copyin(g)
+  // CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g)
+  for (int i = 0; i < 2; ++i)
+    a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+  // CHECK-NEXT: #pragma omp parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(argc) num_threads(a) default(shared) shared(e) reduction(+: h)
+  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: foo();
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/parallel_for_collapse_messages.cpp b/test/OpenMP/parallel_for_collapse_messages.cpp
new file mode 100644
index 0000000..06dfe0f
--- /dev/null
+++ b/test/OpenMP/parallel_for_collapse_messages.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+  #pragma omp parallel for collapse // expected-error {{expected '(' after 'collapse'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse () // expected-error {{expected expression}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 2 {{expression is not an integral constant expression}}
+  // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+  #pragma omp parallel for collapse (argc 
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp parallel for collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for', but found only 1}}
+  // expected-error@+3 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
+  // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}}
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (S) // expected-error {{'S' does not refer to a value}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel for collapse // expected-error {{expected '(' after 'collapse'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for collapse () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+  #pragma omp parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}  expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+  #pragma omp parallel for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{expression is not an integral constant expression}}
+  // expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5) 
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+1 {{expression is not an integral constant expression}}
+  #pragma omp parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp parallel for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo();
+  #pragma omp parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for'}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/parallel_for_copyin_messages.cpp b/test/OpenMP/parallel_for_copyin_messages.cpp
new file mode 100644
index 0000000..2ebc2de
--- /dev/null
+++ b/test/OpenMP/parallel_for_copyin_messages.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4 &operator=(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+  S5 &operator=(const S5 &s5) { return *this; }
+
+public:
+  S5(int v) : a(v) {}
+};
+template <class T>
+class ST {
+public:
+  static T s;
+};
+
+S2 k;
+S3 h;
+S4 l(3); // expected-note {{'l' defined here}}
+S5 m(4); // expected-note {{'m' defined here}}
+#pragma omp threadprivate(h, k, l, m)
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel for copyin // expected-error {{expected '(' after 'copyin'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(ST < int > ::s) // expected-error {{copyin variable must be threadprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_for_default_messages.cpp b/test/OpenMP/parallel_for_default_messages.cpp
new file mode 100644
index 0000000..ed478a8
--- /dev/null
+++ b/test/OpenMP/parallel_for_default_messages.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel for default // expected-error {{expected '(' after 'default'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+    foo();
+#pragma omp parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'default' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel for default(none)
+  for (i = 0; i < argc; ++i)  // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+    foo();
+
+#pragma omp parallel default(none)
+#pragma omp parallel for default(shared)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_for_firstprivate_messages.cpp b/test/OpenMP/parallel_for_firstprivate_messages.cpp
new file mode 100644
index 0000000..99dd68f
--- /dev/null
+++ b/test/OpenMP/parallel_for_firstprivate_messages.cpp
@@ -0,0 +1,252 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel for firstprivate(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel private(i)
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(ba) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(ca) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(da) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp parallel for firstprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(S2::S2s) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(S2::S2sc) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel for'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(m) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i)    // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+#pragma omp parallel shared(xa)
+#pragma omp parallel for firstprivate(xa) // OK: may be firstprivate
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel for firstprivate(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/parallel_for_if_messages.cpp b/test/OpenMP/parallel_for_if_messages.cpp
new file mode 100644
index 0000000..295d739
--- /dev/null
+++ b/test/OpenMP/parallel_for_if_messages.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+  T i;
+  #pragma omp parallel for if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(argc)
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  int i;
+  #pragma omp parallel for if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/parallel_for_lastprivate_messages.cpp b/test/OpenMP/parallel_for_lastprivate_messages.cpp
new file mode 100644
index 0000000..bd1dd4b
--- /dev/null
+++ b/test/OpenMP/parallel_for_lastprivate_messages.cpp
@@ -0,0 +1,226 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note 2 {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note 3 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  I g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                        // expected-note {{'j' defined here}}
+#pragma omp parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel for lastprivate(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note 2 {{'m' defined here}}
+  S6 n(2);
+  int i;
+  int &j = i;                        // expected-note {{'j' defined here}}
+#pragma omp parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(ba)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp parallel for lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel for'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(i)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel private(xa)
+#pragma omp parallel for lastprivate(xa)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel reduction(+ : xa)
+#pragma omp parallel for lastprivate(xa)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/parallel_for_loop_messages.cpp b/test/OpenMP/parallel_for_loop_messages.cpp
new file mode 100644
index 0000000..f029ef4
--- /dev/null
+++ b/test/OpenMP/parallel_for_loop_messages.cpp
@@ -0,0 +1,593 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+class S {
+  int a;
+  S() : a(0) {}
+
+public:
+  S(int v) : a(v) {}
+  S(const S &s) : a(s.a) {}
+};
+
+static int sii;
+#pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+
+int test_iteration_spaces() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  int ii, jj, kk;
+  float fii;
+  double dii;
+#pragma omp parallel for
+  for (int i = 0; i < 10; i += 1) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel for
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel for
+  for (char i = 0; i < 10; i += '\1') {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel for
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+#pragma omp parallel for
+  for (long long i = 0; i < 10; i += 1.5) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel for
+  for (long long i = 0; i < 'z'; i += 1u) {
+    c[i] = a[i] + b[i];
+  }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp parallel for
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp parallel for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp parallel for
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (ii + 1; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (c[ii] = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// Ok to skip parenthesises.
+#pragma omp parallel for
+  for (((ii)) = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0;; i++)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp parallel for
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ++++ii)
+    c[ii] = a[ii];
+
+// Ok but undefined behavior (in general, cannot check that incr
+// is really loop-invariant).
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+// expected-warning@+3 {{relational comparison result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii<10; jj> kk + 2)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; (ii) < 10; ii -= 25)
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; (ii < 10); ii -= 0)
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; ii > 10; (ii += 0))
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for ((ii = 0); ii > 10; (ii -= 0))
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; (ii < 10); (ii -= 0))
+    c[ii] = a[ii];
+
+// expected-note@+2  {{defined as firstprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+#pragma omp parallel for firstprivate(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+// expected-error@+3 {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}}
+// expected-note@+2  {{defined as linear}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be linear, predetermined as private}}
+#pragma omp parallel for linear(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel for private(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel for lastprivate(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+  {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be threadprivate or thread local, predetermined as private}}
+#pragma omp parallel for
+    for (sii = 0; sii < 10; sii += 1)
+      c[sii] = a[sii];
+  }
+
+// expected-error@+2 {{statement after '#pragma omp parallel for' must be a for loop}}
+#pragma omp parallel for
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int(*lb)[4] = nullptr;
+#pragma omp parallel for
+  for (int(*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (int a{0}; a < 10; ++a) {
+  }
+
+  return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag {};
+template <class Iter>
+struct iterator_traits {
+  typedef typename Iter::difference_type difference_type;
+  typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+public:
+  Iter0() {}
+  Iter0(const Iter0 &) {}
+  Iter0 operator++() { return *this; }
+  Iter0 operator--() { return *this; }
+  bool operator<(Iter0 a) { return true; }
+};
+int operator-(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+public:
+  Iter1(float f = 0.0f, double d = 0.0) {}
+  Iter1(const Iter1 &) {}
+  Iter1 operator++() { return *this; }
+  Iter1 operator--() { return *this; }
+  bool operator<(Iter1 a) { return true; }
+  bool operator>=(Iter1 a) { return false; }
+};
+class GoodIter {
+public:
+  GoodIter() {}
+  GoodIter(const GoodIter &) {}
+  GoodIter(int fst, int snd) {}
+  GoodIter &operator=(const GoodIter &that) { return *this; }
+  GoodIter &operator=(const Iter0 &that) { return *this; }
+  GoodIter &operator+=(int x) { return *this; }
+  explicit GoodIter(void *) {}
+  GoodIter operator++() { return *this; }
+  GoodIter operator--() { return *this; }
+  bool operator!() { return true; }
+  bool operator<(GoodIter a) { return true; }
+  bool operator<=(GoodIter a) { return true; }
+  bool operator>=(GoodIter a) { return false; }
+  typedef int difference_type;
+  typedef std::random_access_iterator_tag iterator_category;
+};
+int operator-(GoodIter a, GoodIter b) { return 0; }
+GoodIter operator-(GoodIter a) { return a; }
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+#pragma omp parallel for
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp parallel for
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (GoodIter I(1, 2); I < end; ++I)
+    ++I;
+#pragma omp parallel for
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+#pragma omp parallel for
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (++begin; begin < end; ++begin)
+    ++begin;
+#pragma omp parallel for
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+#pragma omp parallel for
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+// Initializer is constructor without params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+#pragma omp parallel for
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+// Initializer is constructor with all default params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (Iter1 I; I < end1; ++I) {
+  }
+  return 0;
+}
+
+template <typename IT, int ST>
+class TC {
+public:
+  int dotest_lt(IT begin, IT end) {
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+    for (IT I = begin; I < end; I = I + ST) {
+      ++I;
+    }
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+    for (IT I = begin; I <= end; I += ST) {
+      ++I;
+    }
+#pragma omp parallel for
+    for (IT I = begin; I < end; ++I) {
+      ++I;
+    }
+  }
+
+  static IT step() {
+    return IT(ST);
+  }
+};
+template <typename IT, int ST = 0>
+int dotest_gt(IT begin, IT end) {
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+#pragma omp parallel for
+  for (IT I = begin; I < end; I += TC<int, ST>::step()) {
+    ++I;
+  }
+}
+
+void test_with_template() {
+  GoodIter begin, end;
+  TC<GoodIter, 100> t1;
+  TC<GoodIter, -100> t2;
+  t1.dotest_lt(begin, end);
+  t2.dotest_lt(begin, end);         // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+  dotest_gt(begin, end);            // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+  dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+#pragma omp parallel for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    for (int j = 0; j < 10; ++j) {
+      if (a[i] > b[j])
+        break; // OK in nested loop
+    }
+    switch (i) {
+    case 1:
+      b[i]++;
+      break;
+    default:
+      break;
+    }
+    if (c[i] > 10)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+    if (c[i] > 11)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+  }
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; i++) {
+    for (int j = 0; j < 10; j++) {
+      c[i] = a[i] + b[i];
+      if (c[i] > 10) {
+        if (c[i] < 20) {
+          break; // OK
+        }
+      }
+    }
+  }
+}
+
+void test_loop_eh() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+#pragma omp parallel for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    try {
+      for (int j = 0; j < 10; ++j) {
+        if (a[i] > b[j])
+          throw a[i];
+      }
+      throw a[i];
+    } catch (float f) {
+      if (f > 0.1)
+        throw a[i];
+      return; // expected-error {{cannot return from OpenMP region}}
+    }
+    switch (i) {
+    case 1:
+      b[i]++;
+      break;
+    default:
+      break;
+    }
+    for (int j = 0; j < 10; j++) {
+      if (c[i] > 10)
+        throw c[i];
+    }
+  }
+  if (c[9] > 10)
+    throw c[9]; // OK
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
+void test_loop_firstprivate_lastprivate() {
+  S s(4);
+#pragma omp parallel for lastprivate(s) firstprivate(s)
+  for (int i = 0; i < 16; ++i)
+    ;
+}
diff --git a/test/OpenMP/parallel_for_messages.cpp b/test/OpenMP/parallel_for_messages.cpp
new file mode 100644
index 0000000..c9f4df4
--- /dev/null
+++ b/test/OpenMP/parallel_for_messages.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -std=c++11 -o - %s
+
+void foo() {
+}
+
+#pragma omp parallel for // expected-error {{unexpected OpenMP directive '#pragma omp parallel for'}}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel for { // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for(int i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for ( // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for(int i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for [ // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for(int i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for ] // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for(int i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for ) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for(int i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for } // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for(int i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for
+  for(int i = 0; i < argc; ++i) foo();
+  // expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  #pragma omp parallel for unknown()
+  for(int i = 0; i < argc; ++i) foo();
+  L1:
+    for(int i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for
+  for(int i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for
+    for(int i = 0; i < argc; ++i)
+  {
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+    argc++;
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    switch(argc) {
+     case (0):
+      #pragma omp parallel for
+      for(int i = 0; i < argc; ++i)
+      {
+        foo();
+        break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+        continue;
+      }
+      default:
+       break;
+    }
+  }
+  #pragma omp parallel for default(none)
+  for (int i = 0; i < 10; ++i)
+  ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+  #pragma omp parallel for
+  for(int i = 0; i < argc; ++i) L2:foo();
+  #pragma omp parallel for
+  for(int i = 0; i < argc; ++i)
+  {
+    return 1; // expected-error {{cannot return from OpenMP region}}
+  }
+
+  [[]] // expected-error {{an attribute list cannot appear here}}
+  #pragma omp parallel for
+  for (int n = 0; n < 100; ++n) {}
+
+  return 0;
+}
+
diff --git a/test/OpenMP/parallel_for_misc_messages.c b/test/OpenMP/parallel_for_misc_messages.c
new file mode 100644
index 0000000..b236a61
--- /dev/null
+++ b/test/OpenMP/parallel_for_misc_messages.c
@@ -0,0 +1,309 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel for'}}
+#pragma omp parallel for
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel for'}}
+#pragma omp parallel for foo
+
+void test_no_clause() {
+  int i;
+#pragma omp parallel for
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{statement after '#pragma omp parallel for' must be a for loop}}
+#pragma omp parallel for
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel for
+  for (i = 0; i < 16; ++i) {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+}
+
+void test_invalid_clause() {
+  int i;
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for foo bar
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for;
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for linear(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for, private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+extern int foo();
+
+void test_collapse() {
+  int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp parallel for collapse
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel for collapse(
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for collapse()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel for collapse(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}  expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel for collapse(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp parallel for collapse 4)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4,
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4, )
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4, , 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+#pragma omp parallel for collapse(4)
+  for (int i1 = 0; i1 < 16; ++i1)
+    for (int i2 = 0; i2 < 16; ++i2)
+      for (int i3 = 0; i3 < 16; ++i3)
+        for (int i4 = 0; i4 < 16; ++i4)
+          foo();
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4, 8)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp parallel for collapse(2.5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp parallel for collapse(foo())
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp parallel for collapse(-5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp parallel for collapse(0)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp parallel for collapse(5 - 5)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_private() {
+  int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel for private(
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for private(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for private(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for private()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for private(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel for private(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel for private(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for private(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for private(x, y, z)
+  for (i = 0; i < 16; ++i) {
+    x = y * i + z;
+  }
+}
+
+void test_lastprivate() {
+  int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for lastprivate(
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for lastprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for lastprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for lastprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for lastprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel for lastprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel for lastprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for lastprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for lastprivate(x, y, z)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_firstprivate() {
+  int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for firstprivate(
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for firstprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for firstprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for firstprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for firstprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel for firstprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel for lastprivate(x) firstprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for lastprivate(x, y) firstprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for lastprivate(x, y, z) firstprivate(x, y, z)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_loop_messages() {
+  float a[100], b[100], c[100];
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp parallel for
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp parallel for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/parallel_for_num_threads_messages.cpp b/test/OpenMP/parallel_for_num_threads_messages.cpp
new file mode 100644
index 0000000..e192898
--- /dev/null
+++ b/test/OpenMP/parallel_for_num_threads_messages.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  T i;
+  #pragma omp parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc)
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  int i;
+  #pragma omp parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/parallel_for_private_messages.cpp b/test/OpenMP/parallel_for_private_messages.cpp
new file mode 100644
index 0000000..7366fe8
--- /dev/null
+++ b/test/OpenMP/parallel_for_private_messages.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;           // expected-note {{'j' defined here}}
+#pragma omp parallel for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(e, g)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel for private(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;           // expected-note {{'j' defined here}}
+#pragma omp parallel for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int i;
+#pragma omp parallel for private(i)
+    for (int k = 0; k < argc; ++k)
+      ++k;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+
+  return 0;
+}
+
diff --git a/test/OpenMP/parallel_for_proc_bind_messages.cpp b/test/OpenMP/parallel_for_proc_bind_messages.cpp
new file mode 100644
index 0000000..0347caf
--- /dev/null
+++ b/test/OpenMP/parallel_for_proc_bind_messages.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'proc_bind' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel for proc_bind(master)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp parallel for proc_bind(spread)
+  for (i = 0; i < argc; ++i)
+    foo();
+  return 0;
+}
diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp
new file mode 100644
index 0000000..8e482ef
--- /dev/null
+++ b/test/OpenMP/parallel_for_reduction_messages.cpp
@@ -0,0 +1,295 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                        // expected-note 4 {{'j' defined here}}
+  S3 &p = k;                       // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i];         // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];               // expected-note 2 {{'q' defined here}}
+  T fl;                            // expected-note {{'fl' defined here}}
+#pragma omp parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)
+#pragma omp parallel for reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp parallel for reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                      // expected-note 2 {{'j' defined here}}
+  S3 &p = k;                       // expected-note 2 {{'p' defined here}}
+  const int &r = da[i];            // expected-note {{'r' defined here}}
+  int &q = qa[i];                  // expected-note {{'q' defined here}}
+  float fl;                        // expected-note {{'fl' defined here}}
+#pragma omp parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(max : argv[1]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)
+#pragma omp parallel for reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp parallel for reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/parallel_for_schedule_messages.cpp b/test/OpenMP/parallel_for_schedule_messages.cpp
new file mode 100644
index 0000000..b03758a
--- /dev/null
+++ b/test/OpenMP/parallel_for_schedule_messages.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  #pragma omp parallel for schedule // expected-error {{expected '(' after 'schedule'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (auto,  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (runtime, 3)  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp parallel for schedule (guided argc
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp parallel for schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (guided, (ST > 0) ? 1 + ST : 2)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'schedule' clause}}
+  // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (dynamic, 1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel for schedule // expected-error {{expected '(' after 'schedule'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (auto,  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (runtime, 3)  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (dynamic, foobool(1) > 0 ? 1 : 2)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'schedule' clause}}
+  // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp parallel for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/parallel_private_messages.cpp b/test/OpenMP/parallel_private_messages.cpp
index 6dc55e5..1cd86d2 100644
--- a/test/OpenMP/parallel_private_messages.cpp
+++ b/test/OpenMP/parallel_private_messages.cpp
@@ -13,7 +13,7 @@
   mutable int a;
 public:
   S2():a(0) { }
-  static float S2s; // expected-note {{predetermined as shared}}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
 };
 const S2 b;
 const S2 ba[5];
@@ -22,9 +22,9 @@
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f; // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
 class S4 { // expected-note {{'S4' declared here}}
   int a;
   S4();
@@ -42,8 +42,8 @@
 #pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}}
 
 int main(int argc, char **argv) {
-  const int d = 5; // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5; // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
   S4 e(4); // expected-note {{'e' defined here}}
   S5 g(5); // expected-note {{'g' defined here}}
   int i;
diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp
new file mode 100644
index 0000000..43ebc01
--- /dev/null
+++ b/test/OpenMP/parallel_reduction_messages.cpp
@@ -0,0 +1,240 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                    // expected-note 4 {{'j' defined here}}
+  S3 &p = k;                   // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i];     // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];           // expected-note 2 {{'q' defined here}}
+  T fl;                        // expected-note {{'fl' defined here}}
+#pragma omp parallel reduction // expected-error {{expected '(' after 'reduction'}}
+  foo();
+#pragma omp parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+#pragma omp parallel reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp parallel reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  foo();
+#pragma omp parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp parallel reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  foo();
+#pragma omp parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  foo();
+#pragma omp parallel reduction(&& : argc)
+  foo();
+#pragma omp parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  foo();
+#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  foo();
+#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  foo();
+#pragma omp parallel reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  foo();
+#pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  foo();
+#pragma omp parallel reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel private(k)
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  foo();
+#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+  for (int i = 0; i < 10; ++i)
+#pragma omp parallel reduction(+ : fl)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+  for (int i = 0; i < 10; ++i)
+#pragma omp parallel reduction(+ : fl)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                  // expected-note 2 {{'j' defined here}}
+  S3 &p = k;                   // expected-note 2 {{'p' defined here}}
+  const int &r = da[i];        // expected-note {{'r' defined here}}
+  int &q = qa[i];              // expected-note {{'q' defined here}}
+  float fl;                    // expected-note {{'fl' defined here}}
+#pragma omp parallel reduction // expected-error {{expected '(' after 'reduction'}}
+  foo();
+#pragma omp parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+#pragma omp parallel reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp parallel reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  foo();
+#pragma omp parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp parallel reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  foo();
+#pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  foo();
+#pragma omp parallel reduction(&& : argc)
+  foo();
+#pragma omp parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(max : argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  foo();
+#pragma omp parallel reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  foo();
+#pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  foo();
+#pragma omp parallel reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel private(k)
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  foo();
+#pragma omp parallel reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+  for (int i = 0; i < 10; ++i)
+#pragma omp parallel reduction(+ : fl)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+  for (int i = 0; i < 10; ++i)
+#pragma omp parallel reduction(+ : fl)
+    foo();
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_ast_print.cpp b/test/OpenMP/parallel_sections_ast_print.cpp
new file mode 100644
index 0000000..43665f7
--- /dev/null
+++ b/test/OpenMP/parallel_sections_ast_print.cpp
@@ -0,0 +1,144 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+struct S {
+  operator T() { return T(); }
+  static T TS;
+#pragma omp threadprivate(TS)
+};
+
+// CHECK:      template <class T = int> struct S {
+// CHECK:        static int TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<int>::TS)
+// CHECK-NEXT: }
+// CHECK:      template <class T = long> struct S {
+// CHECK:        static long TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<long>::TS)
+// CHECK-NEXT: }
+// CHECK:      template <class T> struct S {
+// CHECK:        static T TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S::TS)
+// CHECK:      };
+
+template <typename T, int C>
+T tmain(T argc, T *argv) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+  S<T> s;
+#pragma omp parallel sections
+  {
+    a = 2;
+  }
+#pragma omp parallel sections default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) num_threads(C) copyin(S < T > ::TS) proc_bind(master) reduction(+ : c) reduction(max : e)
+  {
+    foo();
+  }
+#pragma omp parallel sections if (C) num_threads(s) proc_bind(close) reduction(^ : e, f) reduction(&& : g) lastprivate(b, c)
+  {
+    foo();
+#pragma omp section
+    foo();
+  }
+  return 0;
+}
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
+// CHECK-NEXT: int b = argc, c, d, e, f, g;
+// CHECK-NEXT: static int a;
+// CHECK-NEXT: S<int> s;
+// CHECK-NEXT: #pragma omp parallel sections
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections if(5) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp section
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) {
+// CHECK-NEXT: long b = argc, c, d, e, f, g;
+// CHECK-NEXT: static long a;
+// CHECK-NEXT: S<long> s;
+// CHECK-NEXT: #pragma omp parallel sections
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections if(1) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp section
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
+// CHECK-NEXT: T b = argc, c, d, e, f, g;
+// CHECK-NEXT: static T a;
+// CHECK-NEXT: S<T> s;
+// CHECK-NEXT: #pragma omp parallel sections
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections if(C) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp section
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+
+enum Enum {};
+
+int main(int argc, char **argv) {
+  long x;
+  int b = argc, c, d, e, f, g;
+  static int a;
+#pragma omp threadprivate(a)
+  Enum ee;
+// CHECK: Enum ee;
+#pragma omp parallel sections
+  // CHECK-NEXT: #pragma omp parallel sections
+  {
+    a = 2;
+  }
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+#pragma omp parallel sections default(none), private(argc, b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d) reduction(* : e) lastprivate(argv)
+  // CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d) reduction(*: e) lastprivate(argv)
+  {
+    foo();
+#pragma omp section
+    foo();
+#pragma omp section
+    foo();
+  }
+  // CHECK-NEXT: {
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: #pragma omp section
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: #pragma omp section
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: }
+  return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
+}
+
+#endif
diff --git a/test/OpenMP/parallel_sections_copyin_messages.cpp b/test/OpenMP/parallel_sections_copyin_messages.cpp
new file mode 100644
index 0000000..500417e
--- /dev/null
+++ b/test/OpenMP/parallel_sections_copyin_messages.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4 &operator=(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+  S5 &operator=(const S5 &s5) { return *this; }
+
+public:
+  S5(int v) : a(v) {}
+};
+template <class T>
+class ST {
+public:
+  static T s;
+};
+
+S2 k;
+S3 h;
+S4 l(3); // expected-note {{'l' defined here}}
+S5 m(4); // expected-note {{'m' defined here}}
+#pragma omp threadprivate(h, k, l, m)
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel sections copyin // expected-error {{expected '(' after 'copyin'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(i) // expected-error {{copyin variable must be threadprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(ST < int > ::s) // expected-error {{copyin variable must be threadprivate}}
+  {
+    foo();
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_sections_default_messages.cpp b/test/OpenMP/parallel_sections_default_messages.cpp
new file mode 100644
index 0000000..55d5d4f
--- /dev/null
+++ b/test/OpenMP/parallel_sections_default_messages.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+#pragma omp parallel sections default // expected-error {{expected '(' after 'default'}}
+  {
+#pragma omp parallel sections default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+    {
+#pragma omp parallel sections default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+      {
+#pragma omp parallel sections default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+        {
+#pragma omp parallel sections default(shared), default(shared) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'default' clause}}
+          {
+#pragma omp parallel sections default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+            {
+              foo();
+            }
+          }
+        }
+      }
+    }
+  }
+
+#pragma omp parallel sections default(none)
+  {
+    ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+  }
+
+#pragma omp parallel sections default(none)
+  {
+#pragma omp parallel sections default(shared)
+    {
+      ++argc;
+    }
+  }
+  return 0;
+}
diff --git a/test/OpenMP/parallel_sections_firstprivate_messages.cpp b/test/OpenMP/parallel_sections_firstprivate_messages.cpp
new file mode 100644
index 0000000..ffd2b0c
--- /dev/null
+++ b/test/OpenMP/parallel_sections_firstprivate_messages.cpp
@@ -0,0 +1,295 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i;                              // expected-note {{'j' defined here}}
+#pragma omp parallel sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel sections firstprivate(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : i)
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i;                              // expected-note {{'j' defined here}}
+#pragma omp parallel sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(2 * 2) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(ba) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(ca) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(da) // OK
+  {
+    foo();
+  }
+  int xa;
+#pragma omp parallel sections firstprivate(xa) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(S2::S2s) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(S2::S2sc) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(m) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(xa)
+#pragma omp parallel sections firstprivate(xa) // OK: may be firstprivate
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(n) firstprivate(n) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel sections firstprivate(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : i)
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_if_messages.cpp b/test/OpenMP/parallel_sections_if_messages.cpp
new file mode 100644
index 0000000..4af0d85
--- /dev/null
+++ b/test/OpenMP/parallel_sections_if_messages.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+  #pragma omp parallel sections if // expected-error {{expected '(' after 'if'}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if () // expected-error {{expected expression}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc > 0 ? argv[1] : argv[2])
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (S) // expected-error {{'S' does not refer to a value}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(argc)
+  {
+    foo();
+  }
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel sections if // expected-error {{expected '(' after 'if'}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if () // expected-error {{expected expression}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc > 0 ? argv[1] : argv[2])
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/parallel_sections_lastprivate_messages.cpp b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
new file mode 100644
index 0000000..c71c115
--- /dev/null
+++ b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
@@ -0,0 +1,269 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note 2 {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note 3 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  I g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                             // expected-note {{'j' defined here}}
+#pragma omp parallel sections lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel sections lastprivate(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note 2 {{'m' defined here}}
+  S6 n(2);
+  int i;
+  int &j = i;                             // expected-note {{'j' defined here}}
+#pragma omp parallel sections lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(2 * 2) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(ba)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+  int xa;
+#pragma omp parallel sections lastprivate(xa) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel private(xa)
+#pragma omp parallel sections lastprivate(xa)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : xa)
+#pragma omp parallel sections lastprivate(xa)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(n) firstprivate(n) // OK
+  {
+    foo();
+  }
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_messages.cpp b/test/OpenMP/parallel_sections_messages.cpp
new file mode 100644
index 0000000..f6ee2fc
--- /dev/null
+++ b/test/OpenMP/parallel_sections_messages.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -std=c++11 -o - %s
+
+void foo() {
+}
+
+#pragma omp parallel sections // expected-error {{unexpected OpenMP directive '#pragma omp parallel sections'}}
+
+int main(int argc, char **argv) {
+#pragma omp parallel sections {// expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections( // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections[ // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections] // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections } // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections unknown()
+  {
+    foo();
+#pragma omp section
+  L1:
+    foo();
+  }
+#pragma omp parallel sections
+  {
+    ;
+  }
+#pragma omp parallel sections
+  {
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    switch (argc) {
+    case (0):
+#pragma omp parallel sections
+    {
+      foo();
+      break;    // expected-error {{'break' statement not in loop or switch statement}}
+      continue; // expected-error {{'continue' statement not in loop statement}}
+    }
+    default:
+      break;
+    }
+  }
+#pragma omp parallel sections default(none)
+  {
+    ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+  }
+
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp parallel sections
+  {
+  L2:
+    foo();
+  }
+#pragma omp parallel sections
+  {
+    return 1; // expected-error {{cannot return from OpenMP region}}
+  }
+
+  [[]] // expected-error {{an attribute list cannot appear here}}
+#pragma omp parallel sections
+  {
+  }
+
+  return 0;
+}
+
diff --git a/test/OpenMP/parallel_sections_misc_messages.c b/test/OpenMP/parallel_sections_misc_messages.c
new file mode 100644
index 0000000..94f1241
--- /dev/null
+++ b/test/OpenMP/parallel_sections_misc_messages.c
@@ -0,0 +1,260 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+void foo();
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel sections'}}
+#pragma omp parallel sections
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel sections'}}
+#pragma omp parallel sections foo
+
+void test_no_clause() {
+  int i;
+#pragma omp parallel sections
+  {
+    foo();
+  }
+
+// expected-error@+2 {{the statement for '#pragma omp parallel sections' must be a compound statement}}
+#pragma omp parallel sections
+  ++i;
+
+#pragma omp parallel sections
+  {
+    foo();
+    foo(); // expected-error {{statement in 'omp parallel sections' directive must be enclosed into a section region}}
+  }
+
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel sections
+  {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+#pragma omp section
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L3;
+    else if (i == 8) {
+    L3:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+  goto L3; // expected-error {{use of undeclared label 'L3'}}
+}
+
+void test_invalid_clause() {
+  int i;
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections foo bar
+  {
+    foo();
+// expected-error@+1 {{unexpected OpenMP clause 'nowait' in directive '#pragma omp section'}}
+#pragma omp section nowait
+    ;
+  }
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections;
+  {
+    foo();
+  }
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel sections'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections linear(x);
+  {
+    foo();
+  }
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections private(x);
+  {
+    foo();
+  }
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections, private(x);
+  {
+    foo();
+  }
+}
+
+void test_private() {
+  int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel sections private(
+  {
+    foo();
+  }
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections private(,
+  {
+    foo();
+  }
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections private(, )
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections private()
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections private(int)
+  {
+    foo();
+  }
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel sections private(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel sections private(x)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_lastprivate() {
+  int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections lastprivate(
+  {
+    foo();
+  }
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections lastprivate(,
+  {
+    foo();
+  }
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections lastprivate(, )
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections lastprivate()
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections lastprivate(int)
+  {
+    foo();
+  }
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel sections lastprivate(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel sections lastprivate(x)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_firstprivate() {
+  int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections firstprivate(
+  {
+    foo();
+  }
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections firstprivate(,
+  {
+    foo();
+  }
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections firstprivate(, )
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections firstprivate()
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections firstprivate(int)
+  {
+    foo();
+  }
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel sections firstprivate(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel sections lastprivate(x) firstprivate(x)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(x, y) firstprivate(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(x, y, z) firstprivate(x, y, z)
+  {
+    foo();
+  }
+}
+
diff --git a/test/OpenMP/parallel_sections_num_threads_messages.cpp b/test/OpenMP/parallel_sections_num_threads_messages.cpp
new file mode 100644
index 0000000..927e8d7
--- /dev/null
+++ b/test/OpenMP/parallel_sections_num_threads_messages.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  #pragma omp parallel sections num_threads // expected-error {{expected '(' after 'num_threads'}}
+  {foo();}
+  #pragma omp parallel sections num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {foo();}
+  #pragma omp parallel sections num_threads () // expected-error {{expected expression}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {foo();}
+  #pragma omp parallel sections num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  {foo();}
+  #pragma omp parallel sections num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel sections' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  {foo();}
+  #pragma omp parallel sections num_threads (S) // expected-error {{'S' does not refer to a value}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc)
+  {foo();}
+  #pragma omp parallel sections num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  {foo();}
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel sections num_threads // expected-error {{expected '(' after 'num_threads'}}
+  {foo();}
+  #pragma omp parallel sections num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {foo();}
+  #pragma omp parallel sections num_threads () // expected-error {{expected expression}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+  {foo();}
+  #pragma omp parallel sections num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel sections' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  {foo();}
+  #pragma omp parallel sections num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  {foo();}
+  #pragma omp parallel sections num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+  {foo();}
+
+  return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_private_messages.cpp b/test/OpenMP/parallel_sections_private_messages.cpp
new file mode 100644
index 0000000..9bcae83
--- /dev/null
+++ b/test/OpenMP/parallel_sections_private_messages.cpp
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;                         // expected-note {{'j' defined here}}
+#pragma omp parallel sections private // expected-error {{expected '(' after 'private'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(e, g)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyprivate(i) // expected-error {{unexpected OpenMP clause 'copyprivate' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel sections private(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                         // expected-note {{'j' defined here}}
+#pragma omp parallel sections private // expected-error {{expected '(' after 'private'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyprivate(i) // expected-error {{unexpected OpenMP clause 'copyprivate' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int i;
+#pragma omp parallel sections private(i)
+    {
+      foo();
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(i)
+  {
+    foo();
+  }
+
+  return 0;
+}
+
diff --git a/test/OpenMP/parallel_sections_proc_bind_messages.cpp b/test/OpenMP/parallel_sections_proc_bind_messages.cpp
new file mode 100644
index 0000000..9e58a73
--- /dev/null
+++ b/test/OpenMP/parallel_sections_proc_bind_messages.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+#pragma omp parallel sections proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  { foo(); }
+#pragma omp parallel sections proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  { foo(); }
+#pragma omp parallel sections proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'proc_bind' clause}}
+  { foo(); }
+#pragma omp parallel sections proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  { foo(); }
+
+#pragma omp parallel sections proc_bind(master)
+  { ++argc; }
+
+#pragma omp parallel sections proc_bind(close)
+  {
+#pragma omp parallel sections proc_bind(spread)
+    { ++argc; }
+  }
+  return 0;
+}
diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp
new file mode 100644
index 0000000..8b02f23
--- /dev/null
+++ b/test/OpenMP/parallel_sections_reduction_messages.cpp
@@ -0,0 +1,358 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                             // expected-note 4 {{'j' defined here}}
+  S3 &p = k;                            // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i];              // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];                    // expected-note 2 {{'q' defined here}}
+  T fl;                                 // expected-note {{'fl' defined here}}
+#pragma omp parallel sections reduction // expected-error {{expected '(' after 'reduction'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(k)
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel sections reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(fl)
+#pragma omp parallel sections reduction(+ : fl)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(* : fl)
+#pragma omp parallel sections reduction(+ : fl)
+  {
+    foo();
+  }
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                           // expected-note 2 {{'j' defined here}}
+  S3 &p = k;                            // expected-note 2 {{'p' defined here}}
+  const int &r = da[i];                 // expected-note {{'r' defined here}}
+  int &q = qa[i];                       // expected-note {{'q' defined here}}
+  float fl;                             // expected-note {{'fl' defined here}}
+#pragma omp parallel sections reduction // expected-error {{expected '(' after 'reduction'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(max : argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(k)
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel sections reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(fl)
+#pragma omp parallel sections reduction(+ : fl)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(* : fl)
+#pragma omp parallel sections reduction(+ : fl)
+  {
+    foo();
+  }
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_shared_messages.cpp b/test/OpenMP/parallel_sections_shared_messages.cpp
new file mode 100644
index 0000000..d4915c8
--- /dev/null
+++ b/test/OpenMP/parallel_sections_shared_messages.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4);
+  S5 g(5);
+  int i;
+  int &j = i;
+#pragma omp parallel sections shared // expected-error {{expected '(' after 'shared'}}
+  { foo(); }
+#pragma omp parallel sections shared( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections shared() // expected-error {{expected expression}}
+  { foo(); }
+#pragma omp parallel sections shared(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections shared(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections shared(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  { foo(); }
+#pragma omp parallel sections shared(argc)
+  { foo(); }
+#pragma omp parallel sections shared(S1) // expected-error {{'S1' does not refer to a value}}
+  { foo(); }
+#pragma omp parallel sections shared(a, b, c, d, f)
+  { foo(); }
+#pragma omp parallel sections shared(argv[1]) // expected-error {{expected variable name}}
+  { foo(); }
+#pragma omp parallel sections shared(ba)
+  { foo(); }
+#pragma omp parallel sections shared(ca)
+  { foo(); }
+#pragma omp parallel sections shared(da)
+  { foo(); }
+#pragma omp parallel sections shared(e, g)
+  { foo(); }
+#pragma omp parallel sections shared(h) // expected-error {{threadprivate or thread local variable cannot be shared}}
+  { foo(); }
+#pragma omp parallel sections private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+  { foo(); }
+#pragma omp parallel sections firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+  { foo(); }
+#pragma omp parallel sections private(i)
+  {
+#pragma omp parallel sections shared(i)
+    {
+#pragma omp parallel sections shared(j)
+      { foo(); }
+    }
+  }
+#pragma omp parallel sections firstprivate(i)
+  {
+#pragma omp parallel sections shared(i)
+    {
+#pragma omp parallel sections shared(j)
+      { foo(); }
+    }
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/sections_ast_print.cpp b/test/OpenMP/sections_ast_print.cpp
new file mode 100644
index 0000000..b1a2e03
--- /dev/null
+++ b/test/OpenMP/sections_ast_print.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+#pragma omp parallel
+#pragma omp sections private(argc, b), firstprivate(c, d), lastprivate(d, f) reduction(- : g) nowait
+  {
+    foo();
+  }
+  // CHECK-NEXT: #pragma omp parallel
+  // CHECK-NEXT: #pragma omp sections private(argc,b) firstprivate(c,d) lastprivate(d,f) reduction(-: g) nowait
+  // CHECK-NEXT: {
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: }
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp parallel
+#pragma omp sections private(argc, b), firstprivate(argv, c), lastprivate(d, f) reduction(+ : g) nowait
+  {
+#pragma omp section
+    foo();
+#pragma omp section
+    foo();
+  }
+  // CHECK-NEXT: #pragma omp parallel
+  // CHECK-NEXT: #pragma omp sections private(argc,b) firstprivate(argv,c) lastprivate(d,f) reduction(+: g) nowait
+  // CHECK-NEXT: {
+  // CHECK-NEXT: #pragma omp section
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: #pragma omp section
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: }
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/sections_firstprivate_messages.cpp b/test/OpenMP/sections_firstprivate_messages.cpp
new file mode 100644
index 0000000..b030ce5
--- /dev/null
+++ b/test/OpenMP/sections_firstprivate_messages.cpp
@@ -0,0 +1,335 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                           // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp sections' directive into a parallel or another task region?}}
+#pragma omp sections firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel private(i)      // expected-note {{defined as private}}
+#pragma omp sections firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp sections firstprivate(i)  // expected-error {{firstprivate variable must be shared}}
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(2 * 2) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(ba) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(ca) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(da) // OK
+  {
+    foo();
+  }
+  int xa;
+#pragma omp parallel
+#pragma omp sections firstprivate(xa) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(S2::S2s) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(S2::S2sc) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(m) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(xa)
+#pragma omp sections firstprivate(xa) // OK: may be firstprivate
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(n) firstprivate(n) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                           // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp sections' directive into a parallel or another task region?}}
+#pragma omp sections firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel private(i)      // expected-note {{defined as private}}
+#pragma omp sections firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp sections firstprivate(i)  // expected-error {{firstprivate variable must be shared}}
+  {
+    foo();
+  }
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/sections_lastprivate_messages.cpp b/test/OpenMP/sections_lastprivate_messages.cpp
new file mode 100644
index 0000000..54c6005
--- /dev/null
+++ b/test/OpenMP/sections_lastprivate_messages.cpp
@@ -0,0 +1,309 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note 2 {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note 3 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  I g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp sections lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                          // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp sections' directive into a parallel or another task region?}}
+#pragma omp sections lastprivate(i) // expected-error {{lastprivate variable must be shared}}
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note 2 {{'m' defined here}}
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp sections lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(2 * 2) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(ba)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+  int xa;
+#pragma omp parallel
+#pragma omp sections lastprivate(xa) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel private(xa)     // expected-note {{defined as private}}
+#pragma omp sections lastprivate(xa) // expected-error {{lastprivate variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : xa) // expected-note {{defined as reduction}}
+#pragma omp sections lastprivate(xa)   // expected-error {{lastprivate variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(n) firstprivate(n) // OK
+  {
+    foo();
+  }
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/sections_misc_messages.c b/test/OpenMP/sections_misc_messages.c
new file mode 100644
index 0000000..977d154
--- /dev/null
+++ b/test/OpenMP/sections_misc_messages.c
@@ -0,0 +1,293 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+void foo();
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp sections'}}
+#pragma omp sections
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp sections'}}
+#pragma omp sections foo
+
+void test_no_clause() {
+  int i;
+#pragma omp sections
+  {
+    foo();
+  }
+
+// expected-error@+2 {{the statement for '#pragma omp sections' must be a compound statement}}
+#pragma omp sections
+  ++i;
+
+#pragma omp sections
+  {
+    foo();
+    foo(); // expected-error {{statement in 'omp sections' directive must be enclosed into a section region}}
+  }
+
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel
+#pragma omp sections
+  {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+#pragma omp section
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L3;
+    else if (i == 8) {
+    L3:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+  goto L3; // expected-error {{use of undeclared label 'L3'}}
+}
+
+void test_invalid_clause() {
+  int i;
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections foo bar
+  {
+    foo();
+// expected-error@+1 {{unexpected OpenMP clause 'nowait' in directive '#pragma omp section'}}
+#pragma omp section nowait
+    ;
+  }
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections;
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp sections'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections linear(x);
+  {
+    foo();
+  }
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections private(x);
+  {
+    foo();
+  }
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections, private(x);
+  {
+    foo();
+  }
+}
+
+void test_private() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp sections private(
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections private(,
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections private(, )
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections private()
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections private(int)
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp sections private(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp sections private(x)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_lastprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp sections lastprivate(
+  {
+    foo();
+  }
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections lastprivate(,
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections lastprivate(, )
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections lastprivate()
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections lastprivate(int)
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp sections lastprivate(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp sections lastprivate(x)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_firstprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp sections firstprivate(
+  {
+    foo();
+  }
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections firstprivate(,
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections firstprivate(, )
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections firstprivate()
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections firstprivate(int)
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp sections firstprivate(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp sections lastprivate(x) firstprivate(x)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(x, y) firstprivate(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(x, y, z) firstprivate(x, y, z)
+  {
+    foo();
+  }
+}
+
diff --git a/test/OpenMP/sections_private_messages.cpp b/test/OpenMP/sections_private_messages.cpp
new file mode 100644
index 0000000..7f5aa84
--- /dev/null
+++ b/test/OpenMP/sections_private_messages.cpp
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp sections private // expected-error {{expected '(' after 'private'}}
+  {
+    foo();
+  }
+#pragma omp sections private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc)
+  {
+    foo();
+  }
+#pragma omp sections private(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp sections private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp sections private(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp sections private(e, g)
+  {
+    foo();
+  }
+#pragma omp sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  {
+    foo();
+  }
+#pragma omp sections shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp sections private(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp sections private(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp sections private // expected-error {{expected '(' after 'private'}}
+  {
+    foo();
+  }
+#pragma omp sections private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc)
+  {
+    foo();
+  }
+#pragma omp sections private(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp sections private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp sections private(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp sections private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  {
+    foo();
+  }
+#pragma omp sections shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int i;
+#pragma omp sections private(i)
+    {
+      foo();
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp sections private(i)
+  {
+    foo();
+  }
+
+  return 0;
+}
+
diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp
new file mode 100644
index 0000000..8c4bdcc
--- /dev/null
+++ b/test/OpenMP/sections_reduction_messages.cpp
@@ -0,0 +1,413 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                // expected-note 4 {{'j' defined here}}
+  S3 &p = k;               // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];       // expected-note 2 {{'q' defined here}}
+  T fl;                    // expected-note {{'fl' defined here}}
+#pragma omp parallel
+#pragma omp sections reduction // expected-error {{expected '(' after 'reduction'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(k)
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp sections reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(fl)       // expected-note 2 {{defined as private}}
+#pragma omp sections reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(* : fl) // expected-note 2 {{defined as reduction}}
+#pragma omp sections reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}}
+  {
+    foo();
+  }
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;           // expected-note 2 {{'j' defined here}}
+  S3 &p = k;            // expected-note 2 {{'p' defined here}}
+  const int &r = da[i]; // expected-note {{'r' defined here}}
+  int &q = qa[i];       // expected-note {{'q' defined here}}
+  float fl;             // expected-note {{'fl' defined here}}
+#pragma omp parallel
+#pragma omp sections reduction // expected-error {{expected '(' after 'reduction'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(max : argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(k)
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp sections reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(fl)       // expected-note {{defined as private}}
+#pragma omp sections reduction(+ : fl) // expected-error {{reduction variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(* : fl) // expected-note {{defined as reduction}}
+#pragma omp sections reduction(+ : fl) // expected-error {{reduction variable must be shared}}
+  {
+    foo();
+  }
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/simd_aligned_messages.cpp b/test/OpenMP/simd_aligned_messages.cpp
new file mode 100644
index 0000000..84cf40c
--- /dev/null
+++ b/test/OpenMP/simd_aligned_messages.cpp
@@ -0,0 +1,201 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp=libiomp5 %s
+
+struct B {
+  static int ib[20]; // expected-note 0 {{'B::ib' declared here}}
+  static constexpr int bfoo() { return 8; }
+};
+namespace X {
+  B x; // expected-note {{'x' defined here}}
+};
+constexpr int bfoo() { return 4; }
+
+int **z;
+const int C1 = 1;
+const int C2 = 2;
+void test_aligned_colons(int *&rp)
+{
+  int *B = 0;
+  #pragma omp simd aligned(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
+  #pragma omp simd aligned(B::ib:B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  #pragma omp simd aligned(z:B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}}
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
+  #pragma omp simd aligned(X::x : ::z)
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
+  #pragma omp simd aligned(B,rp,::z: X::x)
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(::z)
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd aligned(B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B::ib,B:C1+C2)
+  for (int i = 0; i < 10; ++i) ;
+}
+
+// expected-note@+1 {{'num' defined here}}
+template<int L, class T, class N> T test_template(T* arr, N num) {
+  N i;
+  T sum = (T)0;
+  T ind2 = - num * L;
+  // Negative number is passed as L.
+  // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}}
+  #pragma omp simd aligned(arr:L)
+  for (i = 0; i < num; ++i) {
+    T cur = arr[(int)ind2];
+    ind2 += L;
+    sum += cur;
+  }
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned(num:4)
+  for (i = 0; i < num; ++i);
+  return T();
+}
+
+template<int LEN> int test_warn() {
+  int *ind2 = 0;
+  // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}}
+  #pragma omp simd aligned(ind2:LEN)
+  for (int i = 0; i < 100; i++) {
+    ind2 += LEN;
+  }
+  return 0;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a; // expected-note {{'a' declared here}}
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+};
+const S2 b; // expected-note 1 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+  int a;
+public:
+  S3():a(0) { }
+};
+const S3 ca[5];
+class S4 {
+  int a;
+  S4();
+public:
+  S4(int v):a(v) { }
+};
+class S5 {
+  int a;
+  S5():a(0) {}
+public:
+  S5(int v):a(v) { }
+};
+
+S3 h; // expected-note 2 {{'h' defined here}}
+#pragma omp threadprivate(h)
+
+template<class I, class C> int foomain(I argc, C **argv) {
+  I e(argc);
+  I g(argc);
+  int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
+  // expected-note@+2 {{declared here}}
+  // expected-note@+1 {{reference to 'i' is not a constant expression}}
+  int &j = i;
+  #pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned () // expected-error {{expected expression}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc : 5)
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned(e, g)
+  for (I k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  #pragma omp simd aligned(h)
+  for (I k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned(i)
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel
+  {
+    int *v = 0;
+    I i;
+    #pragma omp simd aligned(v:16)
+    for (I k = 0; k < argc; ++k) { i = k; v += 2; }
+  }
+  float *f;
+  #pragma omp simd aligned(f)
+  for (I k = 0; k < argc; ++k) ++k;
+  int v = 0;
+  // expected-note@+2 {{initializer of 'j' is not a constant expression}}
+  // expected-error@+1 {{expression is not an integral constant expression}}
+  #pragma omp simd aligned(f:j)
+  for (I k = 0; k < argc; ++k) { ++k; v += j; }
+  #pragma omp simd aligned(f)
+  for (I k = 0; k < argc; ++k) ++k;
+  return 0;
+}
+
+// expected-note@+1 2 {{'argc' defined here}}
+int main(int argc, char **argv) {
+  double darr[100];
+  // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+  test_template<-4>(darr, 4);
+  test_warn<4>(); // ok
+  // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+  test_warn<0>();
+
+  int i;
+  int &j = i;
+  #pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}}
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
+  #pragma omp simd aligned (a, b) 
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  #pragma omp simd aligned(h)
+  for (int k = 0; k < argc; ++k) ++k;
+  int *pargc = &argc;
+  foomain<int*,char>(pargc,argv);
+  return 0;
+}
+
diff --git a/test/OpenMP/simd_ast_print.cpp b/test/OpenMP/simd_ast_print.cpp
index efc65c9..4628612 100644
--- a/test/OpenMP/simd_ast_print.cpp
+++ b/test/OpenMP/simd_ast_print.cpp
@@ -14,8 +14,8 @@
   N myind;
   T sum = (T)0;
 // CHECK: T sum = (T)0;
-#pragma omp simd private(myind, g_ind), linear(ind)
-// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind)
+#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr)
+// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr)
   for (i = 0; i < num; ++i) {
     myind = ind;
     T cur = arr[myind];
@@ -35,8 +35,8 @@
 // CHECK: T res;
 // CHECK: T val;
 // CHECK: T lin = 0;
-    #pragma omp simd private(val)  safelen(7) linear(lin : -5)
-// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5)
+    #pragma omp simd private(val)  safelen(7) linear(lin : -5) lastprivate(res)
+// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5) lastprivate(res)
     for (T i = 7; i < m_a; ++i) {
       val = v[i-7] + m_a;
       res = val;
@@ -62,7 +62,7 @@
 template<int LEN> struct S2 {
   static void func(int n, float *a, float *b, float *c) {
     int k1 = 0, k2 = 0;
-#pragma omp simd safelen(LEN) linear(k1,k2:LEN)
+#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN)
     for(int i = 0; i < n; i++) {
       c[i] = a[i] + b[i];
       c[k1] = a[k1] + b[k1];
@@ -77,7 +77,7 @@
 // CHECK: template <int LEN = 4> struct S2 {
 // CHECK-NEXT: static void func(int n, float *a, float *b, float *c)     {
 // CHECK-NEXT:   int k1 = 0, k2 = 0;
-// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4)
+// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4)
 // CHECK-NEXT:   for (int i = 0; i < n; i++) {
 // CHECK-NEXT:     c[i] = a[i] + b[i];
 // CHECK-NEXT:     c[k1] = a[k1] + b[k1];
@@ -97,10 +97,10 @@
   for (int i=0; i < 2; ++i)*a=2;
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
 // CHECK-NEXT: *a = 2;
-#pragma omp simd private(argc, b) collapse(2)
+#pragma omp simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4)
   for (int i = 0; i < 10; ++i)
   for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;}
-// CHECK-NEXT: #pragma omp simd private(argc,b) collapse(2)
+// CHECK-NEXT: #pragma omp simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4)
 // CHECK-NEXT: for (int i = 0; i < 10; ++i)
 // CHECK-NEXT: for (int j = 0; j < 10; ++j) {
 // CHECK-NEXT: foo();
@@ -112,8 +112,8 @@
 // CHECK-NEXT: foo();
   const int CLEN = 4;
 // CHECK-NEXT: const int CLEN = 4;
-  #pragma omp simd linear(a:CLEN) safelen(CLEN) collapse( 1 )
-// CHECK-NEXT: #pragma omp simd linear(a: CLEN) safelen(CLEN) collapse(1)
+  #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 )
+// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1)
   for (int i = 0; i < 10; ++i)foo();
 // CHECK-NEXT: for (int i = 0; i < 10; ++i)
 // CHECK-NEXT: foo();
diff --git a/test/OpenMP/simd_collapse_messages.cpp b/test/OpenMP/simd_collapse_messages.cpp
index eea9596..56523b3 100644
--- a/test/OpenMP/simd_collapse_messages.cpp
+++ b/test/OpenMP/simd_collapse_messages.cpp
@@ -27,8 +27,8 @@
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   #pragma omp simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
-  #pragma omp simd collapse ((ST > 0) ? 1 + ST : 2)
-  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp simd', but found only 1}}
   // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}}
   // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}}
   // expected-error@+1 2 {{expression is not an integral constant expression}}
@@ -43,6 +43,8 @@
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   #pragma omp simd collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}}
   for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp simd'}}
   return argc;
 }
 
@@ -53,10 +55,10 @@
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   #pragma omp simd collapse () // expected-error {{expected expression}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
-  #pragma omp simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
-  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
-  #pragma omp simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
-  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  #pragma omp simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
   #pragma omp simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
   // expected-error@+3 {{expression is not an integral constant expression}}
@@ -69,6 +71,8 @@
   // expected-error@+1 {{expression is not an integral constant expression}}
   #pragma omp simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp simd'}}
   // expected-error@+3 {{statement after '#pragma omp simd' must be a for loop}}
   // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
   #pragma omp simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
diff --git a/test/OpenMP/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp
new file mode 100644
index 0000000..55f6058
--- /dev/null
+++ b/test/OpenMP/simd_lastprivate_messages.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(e, g)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd firstprivate(i) // expected-error {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp simd lastprivate(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note {{'m' defined here}}
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(ba)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp simd lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd firstprivate(g) // expected-error {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(i) // expected-note {{defined as lastprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp simd' directive may not be lastprivate, predetermined as linear}}
+    foo();
+#pragma omp parallel private(xa)
+#pragma omp simd lastprivate(xa) // OK: may be lastprivate
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  return 0;
+}
diff --git a/test/OpenMP/simd_linear_messages.cpp b/test/OpenMP/simd_linear_messages.cpp
index e90bc69..b8b7831 100644
--- a/test/OpenMP/simd_linear_messages.cpp
+++ b/test/OpenMP/simd_linear_messages.cpp
@@ -50,10 +50,11 @@
   // expected-error@+1 {{argument of a linear clause should be of integral or pointer type}}
 #pragma omp simd linear(ind2:L)
   for (i = 0; i < num; ++i) {
-    T cur = arr[ind2];
+    T cur = arr[(int)ind2];
     ind2 += L;
     sum += cur;
   }
+  return T();
 }
 
 template<int LEN> int test_warn() {
diff --git a/test/OpenMP/simd_loop_messages.cpp b/test/OpenMP/simd_loop_messages.cpp
new file mode 100644
index 0000000..ea663fd
--- /dev/null
+++ b/test/OpenMP/simd_loop_messages.cpp
@@ -0,0 +1,579 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+static int sii;
+#pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+
+int test_iteration_spaces() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  int ii, jj, kk;
+  float fii;
+  double dii;
+  #pragma omp simd
+  for (int i = 0; i < 10; i+=1) {
+    c[i] = a[i] + b[i];
+  }
+  #pragma omp simd
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+  #pragma omp simd
+  for (char i = 0; i < 10; i+='\1') {
+    c[i] = a[i] + b[i];
+  }
+  #pragma omp simd
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+  // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  #pragma omp simd
+  for (long long i = 0; i < 10; i+=1.5) {
+    c[i] = a[i] + b[i];
+  }
+  #pragma omp simd
+  for (long long i = 0; i < 'z'; i+=1u) {
+    c[i] = a[i] + b[i];
+  }
+  // expected-error@+2 {{variable must be of integer or random access iterator type}}
+  #pragma omp simd
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+  // expected-error@+2 {{variable must be of integer or random access iterator type}}
+  #pragma omp simd
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+  // expected-error@+2 {{variable must be of integer or random access iterator type}}
+  #pragma omp simd
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (;ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // expected-warning@+3 {{expression result unused}}
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (ii + 1;ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (c[ii] = 0;ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // Ok to skip parenthesises.
+  #pragma omp simd
+  for (((ii)) = 0;ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+  // expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; ; i++)
+    c[i] = a[i];
+
+  // Ok.
+  #pragma omp simd
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+  // Ok.
+  #pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+    // Ok.
+  #pragma omp simd
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ++ ++ ii)
+    c[ii] = a[ii];
+
+  // Ok but undefined behavior (in general, cannot check that incr
+  // is really loop-invariant).
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+  // Ok - step was converted to integer type.
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+  // expected-warning@+3 {{relational comparison result unused}}
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; jj > kk + 2)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+  // expected-warning@+3 {{expression result unused}}
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; (ii) < 10; ii-=25)
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; (ii < 10); ii-=0)
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; ii > 10; (ii+=0))
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; (ii) = (1-1)+(ii))
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for ((ii = 0); ii > 10; (ii-=0))
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; (ii < 10); (ii-=0))
+    c[ii] = a[ii];
+
+  // expected-note@+2  {{defined as private}}
+  // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be private, predetermined as linear}}
+  #pragma omp simd private(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+  // expected-error@+3 {{unexpected OpenMP clause 'shared' in directive '#pragma omp simd'}}
+  // expected-note@+2  {{defined as shared}}
+  // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be shared, predetermined as linear}}
+  #pragma omp simd shared(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+  #pragma omp simd linear(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+  #pragma omp simd lastprivate(ii) linear(jj) collapse(2) // expected-note {{defined as linear}}
+  for (ii = 0; ii < 10; ii++)
+  for (jj = 0; jj < 10; jj++) // expected-error {{loop iteration variable in the associated loop of 'omp simd' directive may not be linear, predetermined as lastprivate}}
+    c[ii] = a[jj];
+
+
+  #pragma omp parallel
+  {
+    // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be threadprivate or thread local, predetermined as linear}}
+    #pragma omp simd
+    for (sii = 0; sii < 10; sii+=1)
+      c[sii] = a[sii];
+  }
+
+  // expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}}
+  #pragma omp simd
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int (*lb)[4] = nullptr;
+  #pragma omp simd
+  for (int (*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (int a{0}; a<10; ++a) {
+  }
+
+  return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag { };
+template <class Iter> struct iterator_traits {
+  typedef typename Iter::difference_type difference_type;
+  typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+  public:
+    Iter0() { }
+    Iter0(const Iter0 &) { }
+    Iter0 operator ++() { return *this; }
+    Iter0 operator --() { return *this; }
+    bool operator <(Iter0 a) { return true; }
+};
+int operator -(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+  public:
+    Iter1(float f=0.0f, double d=0.0) { }
+    Iter1(const Iter1 &) { }
+    Iter1 operator ++() { return *this; }
+    Iter1 operator --() { return *this; }
+    bool operator <(Iter1 a) { return true; }
+    bool operator >=(Iter1 a) { return false; }
+};
+class GoodIter {
+  public:
+    GoodIter() { }
+    GoodIter(const GoodIter &) { }
+    GoodIter(int fst, int snd) { }
+    GoodIter &operator =(const GoodIter &that) { return *this; }
+    GoodIter &operator =(const Iter0 &that) { return *this; }
+    GoodIter &operator +=(int x) { return *this; }
+    explicit GoodIter(void *) { }
+    GoodIter operator ++() { return *this; }
+    GoodIter operator --() { return *this; }
+    bool operator !() { return true; }
+    bool operator <(GoodIter a) { return true; }
+    bool operator <=(GoodIter a) { return true; }
+    bool operator >=(GoodIter a) { return false; }
+    typedef int difference_type;
+    typedef std::random_access_iterator_tag iterator_category;
+};
+int operator -(GoodIter a, GoodIter b) { return 0; }
+GoodIter operator -(GoodIter a) { return a; }
+GoodIter operator -(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator +(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator -(int v, GoodIter a) { return GoodIter(); }
+GoodIter operator +(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+  #pragma omp simd
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+  // expected-error@+2 {{variable must be of integer or random access iterator type}}
+  #pragma omp simd
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (GoodIter I(1,2); I < end; ++I)
+    ++I;
+  #pragma omp simd
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+  #pragma omp simd
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (++begin; begin < end; ++begin)
+    ++begin;
+  #pragma omp simd
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+  #pragma omp simd
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+  // Initializer is constructor without params.
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+  #pragma omp simd
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+  // Initializer is constructor with all default params.
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (Iter1 I; I < end1; ++I) {
+  }
+  return 0;
+}
+
+template <typename IT, int ST> class TC {
+  public:
+    int dotest_lt(IT begin, IT end) {
+      // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+      // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+      #pragma omp simd
+      for (IT I = begin; I < end; I = I + ST) {
+        ++I;
+      }
+      // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+      // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+      #pragma omp simd
+      for (IT I = begin; I <= end; I += ST) {
+        ++I;
+      }
+      #pragma omp simd
+      for (IT I = begin; I < end; ++I) {
+        ++I;
+      }
+    }
+
+    static IT step() {
+      return IT(ST);
+    }
+};
+template <typename IT, int ST=0> int dotest_gt(IT begin, IT end) {
+  // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+  // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+  #pragma omp simd
+  for (IT I = begin; I < end; I+=TC<int,ST>::step()) {
+    ++I;
+  }
+}
+
+void test_with_template() {
+  GoodIter begin, end;
+  TC<GoodIter, 100> t1;
+  TC<GoodIter, -100> t2;
+  t1.dotest_lt(begin, end);
+  t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+  dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+  dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  #pragma omp simd
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    for (int j = 0; j < 10; ++j) {
+      if (a[i] > b[j])
+        break; // OK in nested loop
+    }
+    switch(i) {
+      case 1:
+        b[i]++;
+        break;
+      default:
+        break;
+    }
+    if (c[i] > 10)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+    if (c[i] > 11)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+  }
+
+  #pragma omp simd
+  for (int i = 0; i < 10; i++) {
+    for (int j = 0; j < 10; j++) {
+      c[i] = a[i] + b[i];
+      if (c[i] > 10) {
+        if (c[i] < 20) {
+          break; // OK
+        }
+      }
+    }
+  }
+}
+
+void test_loop_eh() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  #pragma omp simd
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    try { // expected-error {{'try' statement cannot be used in OpenMP simd region}}
+      for (int j = 0; j < 10; ++j) {
+        if (a[i] > b[j])
+          throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+      }
+      throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+    }
+    catch (float f) {
+      if (f > 0.1)
+        throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+      return; // expected-error {{cannot return from OpenMP region}}
+    }
+    switch(i) {
+      case 1:
+        b[i]++;
+        break;
+      default:
+        break;
+    }
+    for (int j = 0; j < 10; j++) {
+      if (c[i] > 10)
+        throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+    }
+  }
+  if (c[9] > 10)
+    throw c[9]; // OK
+
+  #pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
diff --git a/test/OpenMP/simd_metadata.c b/test/OpenMP/simd_metadata.c
index 427461d..a0588ad 100644
--- a/test/OpenMP/simd_metadata.c
+++ b/test/OpenMP/simd_metadata.c
@@ -40,8 +40,8 @@
 
 // Metadata for h1:
 // CHECK: [[LOOP_H1_HEADER:![0-9]+]] = metadata !{metadata [[LOOP_H1_HEADER]], metadata [[LOOP_WIDTH_16:![0-9]+]], metadata [[LOOP_VEC_ENABLE:![0-9]+]]}
-// CHECK: [[LOOP_WIDTH_16]] = metadata !{metadata !"llvm.vectorizer.width", i32 16}
-// CHECK: [[LOOP_VEC_ENABLE]] = metadata !{metadata !"llvm.vectorizer.enable", i1 true}
+// CHECK: [[LOOP_WIDTH_16]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 16}
+// CHECK: [[LOOP_VEC_ENABLE]] = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
 //
 // Metadata for h2:
 // CHECK: [[LOOP_H2_HEADER]] = metadata !{metadata [[LOOP_H2_HEADER]], metadata [[LOOP_VEC_ENABLE]]}
@@ -49,4 +49,3 @@
 // Metadata for h3:
 // CHECK: [[LOOP_H3_HEADER:![0-9]+]] = metadata !{metadata [[LOOP_H3_HEADER]], metadata [[LOOP_VEC_ENABLE]]}
 //
-
diff --git a/test/OpenMP/simd_misc_messages.c b/test/OpenMP/simd_misc_messages.c
index 58f10ac..67edc6d 100644
--- a/test/OpenMP/simd_misc_messages.c
+++ b/test/OpenMP/simd_misc_messages.c
@@ -169,28 +169,28 @@
   #pragma omp simd collapse 4)
   for (i = 0; i < 16; ++i) ;
   // expected-error@+2 {{expected ')'}}
-  // expected-note@+1 {{to match this '('}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
   #pragma omp simd collapse(4
-  for (i = 0; i < 16; ++i) ;
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
   // expected-error@+2 {{expected ')'}}
-  // expected-note@+1 {{to match this '('}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
   #pragma omp simd collapse(4,
-  for (i = 0; i < 16; ++i) ;
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
   // expected-error@+2 {{expected ')'}}
-  // expected-note@+1 {{to match this '('}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
   #pragma omp simd collapse(4,)
-  for (i = 0; i < 16; ++i) ;
-  // xxpected-error@+1 {{expected expression}}
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  // xxpected-error@+1 {{expected expression}} expected-note@+1 {{as specified in 'collapse' clause}}
   #pragma omp simd collapse(4)
-  for (i = 0; i < 16; ++i) ;
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
   // expected-error@+2 {{expected ')'}}
-  // expected-note@+1 {{to match this '('}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
   #pragma omp simd collapse(4 4)
-  for (i = 0; i < 16; ++i) ;
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
   // expected-error@+2 {{expected ')'}}
-  // expected-note@+1 {{to match this '('}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
   #pragma omp simd collapse(4,,4)
-  for (i = 0; i < 16; ++i) ;
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
   #pragma omp simd collapse(4)
   for (int i1 = 0; i1 < 16; ++i1)
     for (int i2 = 0; i2 < 16; ++i2)
@@ -198,9 +198,9 @@
         for (int i4 = 0; i4 < 16; ++i4)
           foo();
   // expected-error@+2 {{expected ')'}}
-  // expected-note@+1 {{to match this '('}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
   #pragma omp simd collapse(4,8)
-  for (i = 0; i < 16; ++i) ;
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
   // expected-error@+1 {{expression is not an integer constant expression}}
   #pragma omp simd collapse(2.5)
   for (i = 0; i < 16; ++i);
@@ -290,6 +290,94 @@
   // expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}}
   #pragma omp simd linear(x,y:0)
   for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as linear}}
+  // expected-error@+1 {{linear variable cannot be lastprivate}}
+  #pragma omp simd linear(x) lastprivate(x)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as lastprivate}}
+  // expected-error@+1 {{lastprivate variable cannot be linear}}
+  #pragma omp simd lastprivate(x) linear(x) 
+  for (i = 0; i < 16; ++i) ;
+
+}
+
+void test_aligned()
+{
+  int i;
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected expression}}
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected expression}}
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd aligned(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd aligned()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd aligned(int)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd aligned(0)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{use of undeclared identifier 'x'}}
+  #pragma omp simd aligned(x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{use of undeclared identifier 'x'}}
+  // expected-error@+1 {{use of undeclared identifier 'y'}}
+  #pragma omp simd aligned(x, y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+3 {{use of undeclared identifier 'x'}}
+  // expected-error@+2 {{use of undeclared identifier 'y'}}
+  // expected-error@+1 {{use of undeclared identifier 'z'}}
+  #pragma omp simd aligned(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+
+  int *x, y, z[25]; // expected-note 4 {{'y' defined here}}
+  #pragma omp simd aligned(x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(z)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd aligned(x:)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(x:,)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(x:1)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(x:2*2)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(x:1,y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(x:1,y,z:1)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x, y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as aligned}}
+  // expected-error@+1 {{a variable cannot appear in more than one aligned clause}}
+  #pragma omp simd aligned(x) aligned(z,x)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+3 {{defined as aligned}}
+  // expected-error@+2 {{a variable cannot appear in more than one aligned clause}}
+  // expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x,y,z) aligned(y,z)
+  for (i = 0; i < 16; ++i) ;
 }
 
 void test_private()
@@ -337,3 +425,131 @@
   for (i = 0; i < 16; ++i) ;
 }
 
+void test_lastprivate()
+{
+  int i;
+  // expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd lastprivate(
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+  // expected-error@+1 2 {{expected expression}}
+  #pragma omp simd lastprivate(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 2 {{expected expression}}
+  #pragma omp simd lastprivate(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd lastprivate()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd lastprivate(int)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd lastprivate(0)
+  for (i = 0; i < 16; ++i) ;
+
+  int x, y, z;
+  #pragma omp simd lastprivate(x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd lastprivate(x, y)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd lastprivate(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+}
+
+void test_reduction()
+{
+  int i, x, y;
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 {{expected identifier}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected identifier}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected expression}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected identifier}}
+  #pragma omp simd reduction(:x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 {{expected identifier}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 {{expected expression}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(+
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  //
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd reduction(+:
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd reduction(+:)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd reduction(+:,y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd reduction(+:x,+:y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected identifier}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(%:x)
+  for (i = 0; i < 16; ++i) ;
+
+  #pragma omp simd reduction(+:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(*:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(-:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(&:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(|:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(^:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(&&:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(||:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(max:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(min:x)
+  for (i = 0; i < 16; ++i) ;
+  struct X { int x; };
+  struct X X;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd reduction(+:X.x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd reduction(+:x+x)
+  for (i = 0; i < 16; ++i) ;
+}
+
+void test_loop_messages()
+{
+  float a[100], b[100], c[100];
+  // expected-error@+2 {{variable must be of integer or pointer type}}
+  #pragma omp simd
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+  // expected-error@+2 {{variable must be of integer or pointer type}}
+  #pragma omp simd
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp
new file mode 100644
index 0000000..347a5c1
--- /dev/null
+++ b/test/OpenMP/simd_reduction_messages.cpp
@@ -0,0 +1,298 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                        // expected-note 4 {{'j' defined here}}
+  S3 &p = k;                       // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i];         // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];               // expected-note 2 {{'q' defined here}}
+  T fl;                            // expected-note {{'fl' defined here}}
+#pragma omp simd reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : j), reduction(+ : q) // OK
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)
+#pragma omp simd reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp simd reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                      // expected-note 2 {{'j' defined here}}
+  S3 &p = k;                       // expected-note 2 {{'p' defined here}}
+  const int &r = da[i];            // expected-note {{'r' defined here}}
+  int &q = qa[i];                  // expected-note {{'q' defined here}}
+  float fl;                        // expected-note {{'fl' defined here}}
+#pragma omp simd reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(max : argv[1]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)
+#pragma omp simd reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp simd reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/single_ast_print.cpp b/test/OpenMP/single_ast_print.cpp
new file mode 100644
index 0000000..65a007e
--- /dev/null
+++ b/test/OpenMP/single_ast_print.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+#pragma omp parallel private(g)
+#pragma omp single private(argc, b), firstprivate(c, d), nowait copyprivate(g)
+  foo();
+  // CHECK-NEXT: #pragma omp parallel private(g)
+  // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait copyprivate(g)
+  // CHECK-NEXT: foo();
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp parallel private(g)
+#pragma omp single private(argc, b), firstprivate(argv, c), nowait copyprivate(g)
+  foo();
+  // CHECK-NEXT: #pragma omp parallel private(g)
+  // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(argv,c) nowait copyprivate(g)
+  // CHECK-NEXT: foo();
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/single_copyprivate_messages.cpp b/test/OpenMP/single_copyprivate_messages.cpp
new file mode 100644
index 0000000..f07ab12
--- /dev/null
+++ b/test/OpenMP/single_copyprivate_messages.cpp
@@ -0,0 +1,157 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+struct S1; // expected-note 2 {{declared here}}
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4 &operator=(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 2 {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+  S5 &operator=(const S5 &s5) { return *this; }
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S2 k;
+S3 h;
+S4 l(3); // expected-note 2 {{'l' defined here}}
+S5 m(4); // expected-note 2 {{'m' defined here}}
+#pragma omp threadprivate(h, k, l, m)
+
+template <class T, class C>
+T tmain(T argc, C **argv) {
+  T i;
+#pragma omp parallel
+#pragma omp single copyprivate // expected-error {{expected '(' after 'copyprivate'}}
+#pragma omp parallel
+#pragma omp single copyprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate() // expected-error {{expected expression}}
+#pragma omp parallel
+#pragma omp single copyprivate(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp parallel
+#pragma omp single copyprivate(l) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}
+#pragma omp parallel
+#pragma omp single copyprivate(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp parallel
+#pragma omp single copyprivate(argv[1]) // expected-error {{expected variable name}}
+#pragma omp parallel // expected-note {{implicitly determined as shared}}
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+#pragma omp parallel
+#pragma omp single copyprivate(m) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}
+  foo();
+#pragma omp parallel private(i)
+  {
+#pragma omp single copyprivate(i)
+    foo();
+  }
+#pragma omp parallel shared(i) // expected-note {{defined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel default(shared) // expected-note {{implicitly determined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel // expected-note {{implicitly determined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel
+#pragma omp single private(i) copyprivate(i) // expected-error {{private variable cannot be copyprivate}} expected-note {{defined as private}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(i) copyprivate(i) // expected-error {{firstprivate variable cannot be copyprivate}} expected-note {{defined as firstprivate}}
+  foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel
+#pragma omp single copyprivate // expected-error {{expected '(' after 'copyprivate'}}
+#pragma omp parallel
+#pragma omp single copyprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate() // expected-error {{expected expression}}
+#pragma omp parallel
+#pragma omp single copyprivate(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp parallel
+#pragma omp single copyprivate(l) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}
+#pragma omp parallel
+#pragma omp single copyprivate(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp parallel
+#pragma omp single copyprivate(argv[1]) // expected-error {{expected variable name}}
+#pragma omp parallel // expected-note {{implicitly determined as shared}}
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+#pragma omp parallel
+#pragma omp single copyprivate(m) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}
+  foo();
+#pragma omp parallel private(i)
+  {
+#pragma omp single copyprivate(i)
+    foo();
+  }
+#pragma omp parallel shared(i) // expected-note {{defined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel default(shared) // expected-note {{implicitly determined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel // expected-note {{implicitly determined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel
+#pragma omp single private(i) copyprivate(i) // expected-error {{private variable cannot be copyprivate}} expected-note {{defined as private}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(i) copyprivate(i) // expected-error {{firstprivate variable cannot be copyprivate}} expected-note {{defined as firstprivate}}
+  foo();
+
+  return tmain(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char>' requested here}}
+}
diff --git a/test/OpenMP/single_firstprivate_messages.cpp b/test/OpenMP/single_firstprivate_messages.cpp
new file mode 100644
index 0000000..6d49882
--- /dev/null
+++ b/test/OpenMP/single_firstprivate_messages.cpp
@@ -0,0 +1,239 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp single firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate() // expected-error {{expected expression}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc)
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  foo();
+#pragma omp parallel
+#pragma omp single linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp single'}}
+  foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                         // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp single' directive into a parallel or another task region?}}
+#pragma omp single firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    foo();
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp single firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(i)
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  foo();
+#pragma omp parallel private(i)    // expected-note {{defined as private}}
+#pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  foo();
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp single firstprivate(i)    // expected-error {{firstprivate variable must be shared}}
+  foo();
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp single firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate() // expected-error {{expected expression}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc)
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(2 * 2) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(ba) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(ca) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(da) // OK
+  foo();
+  int xa;
+#pragma omp parallel
+#pragma omp single firstprivate(xa) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(S2::S2s) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(S2::S2sc) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp single'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(m) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  foo();
+#pragma omp parallel
+#pragma omp single private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  foo();
+#pragma omp parallel shared(xa)
+#pragma omp single firstprivate(xa) // OK: may be firstprivate
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(n) // OK
+  foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                         // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp single' directive into a parallel or another task region?}}
+#pragma omp single firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    foo();
+    v += i;
+  }
+#pragma omp parallel private(i)    // expected-note {{defined as private}}
+#pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  foo();
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp single firstprivate(i)    // expected-error {{firstprivate variable must be shared}}
+  foo();
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/single_misc_messages.c b/test/OpenMP/single_misc_messages.c
new file mode 100644
index 0000000..8667b50
--- /dev/null
+++ b/test/OpenMP/single_misc_messages.c
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+void foo();
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp single'}}
+#pragma omp single
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp single'}}
+#pragma omp single foo
+
+void test_no_clause() {
+  int i;
+#pragma omp single
+  foo();
+
+#pragma omp single
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel
+#pragma omp single
+  {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+}
+
+void test_invalid_clause() {
+  int i;
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single foo bar
+  foo();
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single;
+  foo();
+#pragma omp parallel
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp single'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single linear(x);
+  foo();
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single private(x);
+  foo();
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single, private(x);
+  foo();
+}
+
+void test_private() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp single private(
+  foo();
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp single private(,
+  foo();
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp single private(, )
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp single private()
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp single private(int)
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp single private(0)
+  foo();
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp single private(x)
+  foo();
+#pragma omp parallel
+#pragma omp single private(x, y)
+  foo();
+#pragma omp parallel
+#pragma omp single private(x, y, z)
+  foo();
+}
+
+void test_firstprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp single firstprivate(
+  foo();
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp single firstprivate(,
+  foo();
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp single firstprivate(, )
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp single firstprivate()
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp single firstprivate(int)
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp single firstprivate(0)
+  foo();
+}
+
diff --git a/test/OpenMP/single_private_messages.cpp b/test/OpenMP/single_private_messages.cpp
new file mode 100644
index 0000000..1414a92
--- /dev/null
+++ b/test/OpenMP/single_private_messages.cpp
@@ -0,0 +1,140 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp single private // expected-error {{expected '(' after 'private'}}
+  foo();
+#pragma omp single private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private() // expected-error {{expected expression}}
+  foo();
+#pragma omp single private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp single private(argc)
+  foo();
+#pragma omp single private(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp single private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  foo();
+#pragma omp single private(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp single private(e, g)
+  foo();
+#pragma omp single private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  foo();
+#pragma omp single shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp single'}}
+  foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp single private(i)
+    foo();
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp single private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  foo();
+#pragma omp single private(i)
+  foo();
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp single private // expected-error {{expected '(' after 'private'}}
+  foo();
+#pragma omp single private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private() // expected-error {{expected expression}}
+  foo();
+#pragma omp single private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp single private(argc)
+  foo();
+#pragma omp single private(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp single private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  foo();
+#pragma omp single private(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp single private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  foo();
+#pragma omp single private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  foo();
+#pragma omp single shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp single'}}
+  foo();
+#pragma omp parallel
+  {
+    int i;
+#pragma omp single private(i)
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp single private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  foo();
+#pragma omp single private(i)
+  foo();
+
+  return 0;
+}
+
diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp
index 4b4f9e0..491f30a 100644
--- a/test/OpenMP/threadprivate_messages.cpp
+++ b/test/OpenMP/threadprivate_messages.cpp
@@ -55,17 +55,17 @@
 int &f = a; // expected-note {{'f' defined here}}
 #pragma omp threadprivate (f) // expected-error {{arguments of '#pragma omp threadprivate' cannot be of reference type 'int &'}}
 
-class Class {
+class TestClass {
   private:
     int a; // expected-note {{declared here}}
     static int b; // expected-note {{'b' declared here}}
-    Class() : a(0){}
+    TestClass() : a(0){}
   public:
-    Class (int aaa) : a(aaa) {}
+    TestClass (int aaa) : a(aaa) {}
 #pragma omp threadprivate (b, a) // expected-error {{'a' is not a global variable, static local variable or static data member}}
 } g(10);
 #pragma omp threadprivate (b) // expected-error {{use of undeclared identifier 'b'}}
-#pragma omp threadprivate (Class::b) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'Class::b' variable declaration}}
+#pragma omp threadprivate (TestClass::b) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'TestClass::b' variable declaration}}
 #pragma omp threadprivate (g)
 
 namespace ns {
@@ -108,10 +108,12 @@
 
 int main(int argc, char **argv) { // expected-note {{'argc' defined here}}
 
-  int x, y = argc; // expected-note {{'y' defined here}}
+  int x, y = argc; // expected-note 2 {{'y' defined here}}
   static double d1;
   static double d2;
   static double d3; // expected-note {{'d3' defined here}}
+  static TestClass LocalClass(y); // expected-error {{variable with local storage in initial value of threadprivate variable}}
+#pragma omp threadprivate(LocalClass)
 
   d.a = a;
   d2++;
diff --git a/test/PCH/cxx-key-functions.cpp b/test/PCH/cxx-key-functions.cpp
new file mode 100644
index 0000000..9e7411c
--- /dev/null
+++ b/test/PCH/cxx-key-functions.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -x c++ -include %s -emit-llvm-only %s
+// RUN: %clang_cc1 -x c++ -emit-pch %s -o %t
+// RUN: %clang_cc1 -include-pch %t -emit-llvm-only %s
+
+#ifndef HEADER
+#define HEADER
+
+struct S00 { virtual void f(); };
+struct S01 { virtual void f(); };
+struct S02 { virtual void f(); };
+struct S03 { virtual void f(); };
+struct S04 { virtual void f(); };
+struct S05 { virtual void f(); };
+struct S06 { virtual void f(); };
+struct S07 { virtual void f(); };
+struct S08 { virtual void f(); };
+struct S09 { virtual void f(); };
+struct S10 { virtual void f(); };
+struct S11 { virtual void f(); };
+struct S12 { virtual void f(); };
+struct S13 { virtual void f(); };
+struct S14 { virtual void f(); };
+struct S15 { virtual void f(); };
+struct S16 { virtual void f(); };
+struct S17 { virtual void f(); };
+struct S18 { virtual void f(); };
+struct S19 { virtual void f(); };
+struct S20 { virtual void f(); };
+struct S21 { virtual void f(); };
+struct S22 { virtual void f(); };
+struct S23 { virtual void f(); };
+struct S24 { virtual void f(); };
+struct S25 { virtual void f(); };
+struct S26 { virtual void f(); };
+struct S27 { virtual void f(); };
+struct S28 { virtual void f(); };
+struct S29 { virtual void f(); };
+struct S30 { virtual void f(); };
+struct S31 { virtual void f(); };
+struct S32 { virtual void f(); };
+struct S33 { virtual void f(); };
+struct S34 { virtual void f(); };
+struct S35 { virtual void f(); };
+struct S36 { virtual void f(); };
+struct S37 { virtual void f(); };
+struct S38 { virtual void f(); };
+struct S39 { virtual void f(); };
+struct S40 { virtual void f(); };
+struct S41 { virtual void f(); };
+struct S42 { virtual void f(); };
+struct S43 { virtual void f(); };
+struct S44 { virtual void f(); };
+struct S45 { virtual void f(); };
+struct S46 { virtual void f(); };
+struct S47 { virtual void f(); };
+struct S48 { virtual void f(); };
+struct S49 { virtual void f(); };
+struct S50 { virtual void f(); };
+struct S51 { virtual void f(); };
+struct S52 { virtual void f(); };
+struct S53 { virtual void f(); };
+struct S54 { virtual void f(); };
+struct S55 { virtual void f(); };
+struct S56 { virtual void f(); };
+struct S57 { virtual void f(); };
+struct S58 { virtual void f(); };
+struct S59 { virtual void f(); };
+struct S60 { virtual void f(); };
+struct S61 { virtual void f(); };
+struct S62 { virtual void f(); };
+struct S63 { virtual void f(); };
+struct S64 { virtual void f(); };
+struct S65 { virtual void f(); };
+struct S66 { virtual void f(); };
+struct S67 { virtual void f(); };
+struct S68 { virtual void f(); };
+struct S69 { virtual void f(); };
+
+struct Test {
+  // Deserializing this key function should cause the key functions
+  // table to get resized.
+  virtual void f(S00, S01, S02, S03, S04, S05, S06, S07, S08, S09,
+                 S10, S11, S12, S13, S14, S15, S16, S17, S18, S19,
+                 S20, S21, S22, S23, S24, S25, S26, S27, S28, S29,
+                 S30, S31, S32, S33, S34, S35, S36, S37, S38, S39,
+                 S40, S41, S42, S43, S44, S45, S46, S47, S48, S49,
+                 S50, S51, S52, S53, S54, S55, S56, S57, S58, S59,
+                 S60, S61, S62, S63, S64, S65, S66, S67, S68, S69);
+  virtual void g();
+};
+
+#else
+
+void Test::g() {}
+void h(Test &t) { t.g(); }
+
+#endif
diff --git a/test/PCH/pragma-loop.cpp b/test/PCH/pragma-loop.cpp
new file mode 100644
index 0000000..6258b37
--- /dev/null
+++ b/test/PCH/pragma-loop.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -emit-pch -o %t.a %s
+// RUN: %clang_cc1 -include-pch %t.a %s -ast-print -o - | FileCheck %s
+
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// reversed. The checks are consequently in the reverse order below.
+
+// CHECK: #pragma clang loop unroll_count(16)
+// CHECK: #pragma clang loop interleave_count(8)
+// CHECK: #pragma clang loop vectorize_width(4)
+// CHECK: #pragma clang loop unroll(disable)
+// CHECK: #pragma clang loop interleave(disable)
+// CHECK: #pragma clang loop vectorize(enable)
+// CHECK: #pragma clang loop unroll(enable)
+// CHECK: #pragma clang loop interleave(enable)
+// CHECK: #pragma clang loop vectorize(disable)
+
+#ifndef HEADER
+#define HEADER
+
+class pragma_test {
+public:
+  inline void run1(int *List, int Length) {
+    int i = 0;
+#pragma clang loop vectorize_width(4)
+#pragma clang loop interleave_count(8)
+#pragma clang loop unroll_count(16)
+    while (i < Length) {
+      List[i] = i;
+      i++;
+    }
+  }
+
+  inline void run2(int *List, int Length) {
+    int i = 0;
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave(disable)
+#pragma clang loop unroll(disable)
+    while (i - 1 < Length) {
+      List[i] = i;
+      i++;
+    }
+  }
+
+  inline void run3(int *List, int Length) {
+    int i = 0;
+#pragma clang loop vectorize(disable)
+#pragma clang loop interleave(enable)
+#pragma clang loop unroll(enable)
+    while (i - 3 < Length) {
+      List[i] = i;
+      i++;
+    }
+  }
+};
+
+#else
+
+void test() {
+  int List[100];
+
+  pragma_test pt;
+
+  pt.run1(List, 100);
+  pt.run2(List, 100);
+  pt.run3(List, 100);
+}
+
+#endif
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index badd204..d7ea20b 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -1,98 +1,58 @@
-// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions  -Wno-missing-declarations -x objective-c++ %s
-__stdcall int func0();
-int __stdcall func();
-typedef int (__cdecl *tptr)();
-void (*__fastcall fastpfunc)();
-struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; /* expected-warning{{__declspec attribute 'novtable' is not supported}} */
-extern __declspec(dllimport) void __stdcall VarR4FromDec();
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -Wno-missing-declarations -verify -fms-extensions  %s
+__stdcall int func0(void);
+int __stdcall func(void);
+typedef int (__cdecl *tptr)(void);
+void (*__fastcall fastpfunc)(void);
+extern __declspec(dllimport) void __stdcall VarR4FromDec(void);
 __declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix);
-__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory ); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */
+__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx(void *_Memory); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */
 typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
 
-void * __ptr64 PtrToPtr64(const void *p)
-{
+void * __ptr64 PtrToPtr64(const void *p) {
   return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p );
 }
-void * __ptr32 PtrToPtr32(const void *p)
-{
+
+void * __ptr32 PtrToPtr32(const void *p) {
   return((void * __ptr32) (unsigned __int32) (ULONG_PTR)p );
 }
 
-void __forceinline InterlockedBitTestAndSet (long *Base, long Bit)
-{
-  // FIXME: Re-enable this once MS inline asm stabilizes.
-#if 0
-  __asm {
-    mov eax, Bit
-    mov ecx, Base
-    lock bts [ecx], eax
-    setc al
-  };
-#endif
+/* Both inline and __forceinline is OK. */
+inline void __forceinline pr8264(void) {}
+__forceinline void inline pr8264_1(void) {}
+void inline __forceinline pr8264_2(void) {}
+void __forceinline inline pr8264_3(void) {}
+/* But duplicate __forceinline causes warning. */
+void __forceinline __forceinline pr8264_4(void) {  /* expected-warning{{duplicate '__forceinline' declaration specifier}} */
 }
 
-// Both inline and __forceinline is OK.
-inline void __forceinline pr8264() {
-}
-__forceinline void inline pr8264_1() {
-}
-void inline __forceinline pr8264_2() {
-}
-void __forceinline inline pr8264_3() {
-}
-// But duplicate __forceinline causes warning.
-void __forceinline __forceinline pr8264_4() {  // expected-warning{{duplicate '__forceinline' declaration specifier}}
-}
+_inline int foo99(void) { return 99; }
 
-_inline int foo99() { return 99; }
-
-void test_ms_alignof_alias() {
+void test_ms_alignof_alias(void) {
   unsigned int s = _alignof(int);
   s = __builtin_alignof(int);
 }
 
-void *_alloca(int);
-
-void foo() {
-  __declspec(align(16)) int *buffer = (int *)_alloca(9);
-}
-
-typedef bool (__stdcall __stdcall *blarg)(int);
-
-void local_callconv()
-{
-  bool (__stdcall *p)(int);
-}
-
-// Charify extension.
+/* Charify extension. */
 #define FOO(x) #@x
 char x = FOO(a);
 
 typedef enum E { e1 };
 
+enum __declspec(deprecated) E2 { i, j, k }; /* expected-note {{'E2' has been explicitly marked deprecated here}} */
+__declspec(deprecated) enum E3 { a, b, c } e; /* expected-note {{'e' has been explicitly marked deprecated here}} */
 
-enum __declspec(deprecated) E2 { i, j, k }; // expected-note {{'E2' has been explicitly marked deprecated here}}
-__declspec(deprecated) enum E3 { a, b, c } e; // expected-note {{'e' has been explicitly marked deprecated here}}
-
-void deprecated_enum_test(void)
-{
-  // Test to make sure the deprecated warning follows the right thing
-  enum E2 e1;  // expected-warning {{'E2' is deprecated}}
-  enum E3 e2; // No warning expected, the deprecation follows the variable
-  enum E3 e3 = e;  // expected-warning {{'e' is deprecated}}
+void deprecated_enum_test(void) {
+  /* Test to make sure the deprecated warning follows the right thing */
+  enum E2 e1;  /* expected-warning {{'E2' is deprecated}} */
+  enum E3 e2; /* No warning expected, the deprecation follows the variable */
+  enum E3 e3 = e;  /* expected-warning {{'e' is deprecated}} */
 }
 
 /* Microsoft attribute tests */
-[repeatable][source_annotation_attribute( Parameter|ReturnValue )]
-struct SA_Post{ SA_Post(); int attr; };
-
 [returnvalue:SA_Post( attr=1)]
 int foo1([SA_Post(attr=1)] void *param);
 
-
-
-void ms_intrinsics(int a)
-{
+void ms_intrinsics(int a) {
   __noop();
   __assume(a);
   __debugbreak();
@@ -115,17 +75,6 @@
 struct __declspec(deprecated frobble "testing") S5 {};  /* expected-warning {{__declspec attribute 'frobble' is not supported}} expected-warning {{__declspec attribute '"testing"' is not supported}} */
 struct __declspec(unknown(12) deprecated) S6 {};	/* expected-warning {{__declspec attribute 'unknown' is not supported}}*/
 
-struct S7 {
-	int foo() { return 12; }
-	__declspec(property(get=foo) deprecated) int t; // expected-note {{'t' has been explicitly marked deprecated here}}
-};
-
-/* Technically, this is legal (though it does nothing) */
-__declspec() void quux( void ) {
-  struct S7 s;
-  int i = s.t;	/* expected-warning {{'t' is deprecated}} */
-}
-
 int * __sptr psp;
 int * __uptr pup;
 /* Either ordering is acceptable */
diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp
index 5f3c2a2..a35d069 100644
--- a/test/Parser/MicrosoftExtensions.cpp
+++ b/test/Parser/MicrosoftExtensions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -fms-compatibility -fdelayed-template-parsing
+// RUN: %clang_cc1 %s -triple i386-mingw32 -std=c++11 -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -fms-compatibility -fdelayed-template-parsing
 
 /* Microsoft attribute tests */
 [repeatable][source_annotation_attribute( Parameter|ReturnValue )]
@@ -118,7 +118,7 @@
 
 COM_CLASS_TEMPLATE_REF<int, __uuidof(struct_with_uuid)> good_template_arg;
 
-COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // expected-error {{non-type template argument of type 'const _GUID' is not a constant expression}}
+COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // expected-error {{non-type template argument of type 'const _GUID' cannot be converted to a value of type 'const GUID *' (aka 'const _GUID *')}}
 
 namespace PR16911 {
 struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
@@ -227,103 +227,6 @@
 
 __int64 x7 = __int64(0);
 
-
-namespace If_exists_test {
-
-class IF_EXISTS {
-private:
-    typedef int Type;
-};
-
-int __if_exists_test() {
-  int b=0;
-  __if_exists(IF_EXISTS::Type) {
-     b++;
-     b++;
-  }
-  __if_exists(IF_EXISTS::Type_not) {
-     this will not compile.
-  }
-  __if_not_exists(IF_EXISTS::Type) {
-     this will not compile.
-  }
-  __if_not_exists(IF_EXISTS::Type_not) {
-     b++;
-     b++;
-  }
-}
-
-
-__if_exists(IF_EXISTS::Type) {
-  int var23;
-}
-
-__if_exists(IF_EXISTS::Type_not) {
- this will not compile.
-}
-
-__if_not_exists(IF_EXISTS::Type) {
- this will not compile.
-}
-
-__if_not_exists(IF_EXISTS::Type_not) {
-  int var244;
-}
-
-int __if_exists_init_list() {
-
-  int array1[] = {
-    0,
-    __if_exists(IF_EXISTS::Type) {2, }
-    3
-  };
-
-  int array2[] = {
-    0,
-    __if_exists(IF_EXISTS::Type_not) { this will not compile }
-    3
-  };
-
-  int array3[] = {
-    0,
-    __if_not_exists(IF_EXISTS::Type_not) {2, }
-    3
-  };
-
-  int array4[] = {
-    0,
-    __if_not_exists(IF_EXISTS::Type) { this will not compile }
-    3
-  };
-
-}
-
-
-class IF_EXISTS_CLASS_TEST {
-  __if_exists(IF_EXISTS::Type) {
-    // __if_exists, __if_not_exists can nest
-    __if_not_exists(IF_EXISTS::Type_not) {
-      int var123;
-    }
-    int var23;
-  }
-
-  __if_exists(IF_EXISTS::Type_not) {
-   this will not compile.
-  }
-
-  __if_not_exists(IF_EXISTS::Type) {
-   this will not compile.
-  }
-
-  __if_not_exists(IF_EXISTS::Type_not) {
-    int var244;
-  }
-};
-
-}
-
-
 int __identifier(generic) = 3;
 int __identifier(int) = 4;
 struct __identifier(class) { __identifier(class) *__identifier(for); };
@@ -426,3 +329,31 @@
   sp.V11++;
   ++sp.V11;
 }
+
+//expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}}
+#define and foo
+
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; // expected-warning{{__declspec attribute 'novtable' is not supported}}
+
+typedef bool (__stdcall __stdcall *blarg)(int);
+
+void local_callconv() {
+  bool (__stdcall *p)(int);
+}
+
+struct S7 {
+	int foo() { return 12; }
+	__declspec(property(get=foo) deprecated) int t; // expected-note {{'t' has been explicitly marked deprecated here}}
+};
+
+// Technically, this is legal (though it does nothing)
+__declspec() void quux( void ) {
+  struct S7 s;
+  int i = s.t;	// expected-warning {{'t' is deprecated}}
+}
+
+void *_alloca(int);
+
+void foo(void) {
+  __declspec(align(16)) int *buffer = (int *)_alloca(9);
+}
diff --git a/test/Parser/MicrosoftExtensionsInlineAsm.c b/test/Parser/MicrosoftExtensionsInlineAsm.c
new file mode 100644
index 0000000..a973152
--- /dev/null
+++ b/test/Parser/MicrosoftExtensionsInlineAsm.c
@@ -0,0 +1,13 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions  %s
+// expected-no-diagnostics
+
+void __forceinline InterlockedBitTestAndSet (long *Base, long Bit)
+{
+  __asm {
+    mov eax, Bit
+    mov ecx, Base
+    lock bts [ecx], eax
+    setc al
+  };
+}
diff --git a/test/Parser/altivec-csk-bool.c b/test/Parser/altivec-csk-bool.c
index 88d78c8..c1c2539 100644
--- a/test/Parser/altivec-csk-bool.c
+++ b/test/Parser/altivec-csk-bool.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -faltivec -fsyntax-only %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -faltivec -fsyntax-only %s
 
 // PR16456: Verify that bool, true, false are treated as context-sensitive
 // keywords (and therefore available for use as identifiers) when in
diff --git a/test/Parser/altivec.c b/test/Parser/altivec.c
index 436a3af..0b8147a 100644
--- a/test/Parser/altivec.c
+++ b/test/Parser/altivec.c
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -faltivec -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -faltivec -fsyntax-only -verify %s
 
 __vector char vv_c;
 __vector signed char vv_sc;
diff --git a/test/Parser/brackets.c b/test/Parser/brackets.c
new file mode 100644
index 0000000..2750d0e
--- /dev/null
+++ b/test/Parser/brackets.c
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -fixit %t -x c -DFIXIT
+// RUN: %clang_cc1 -fsyntax-only %t -x c -DFIXIT
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s -strict-whitespace
+
+void test1() {
+  int a[] = {0,1,1,2,3};
+  int []b = {0,1,4,9,16};
+  // expected-error@-1{{brackets go after the identifier}}
+  // CHECK: {{^}}  int []b = {0,1,4,9,16};
+  // CHECK: {{^}}      ~~ ^
+  // CHECK: {{^}}         []
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:9}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:10-[[@LINE-6]]:10}:"[]"
+
+  int c = a[0];
+  int d = b[0]; // No undeclared identifer error here.
+
+  int *e = a;
+  int *f = b; // No undeclared identifer error here.
+}
+
+struct S {
+  int [1][1]x;
+  // expected-error@-1{{brackets go after the identifier}}
+  // CHECK: {{^}}  int [1][1]x;
+  // CHECK: {{^}}      ~~~~~~ ^
+  // CHECK: {{^}}             [1][1]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:13}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:14-[[@LINE-6]]:14}:"[1][1]"
+} s;
+
+#ifndef FIXIT
+void test2() {
+  int [][][];
+  // expected-error@-1{{expected identifier or '('}}
+  // CHECK: {{^}}  int [][][];
+  // CHECK: {{^}}      ^
+  // CHECK-NOT: fix-it
+  struct T {
+    int [];
+    // expected-error@-1{{expected member name or ';' after declaration specifiers}}
+    // CHECK: {{^}}    int [];
+    // CHECK: {{^}}    ~~~ ^
+    // CHECK-NOT: fix-it
+  };
+}
+
+void test3() {
+  int [5] *;
+  // expected-error@-1{{expected identifier or '('}}
+  // CHECK: {{^}}  int [5] *;
+  // CHECK: {{^}}           ^
+  // CHECK-NOT: fix-it
+  // expected-error@-5{{brackets go after the identifier}}
+  // CHECK: {{^}}  int [5] *;
+  // CHECK: {{^}}      ~~~~ ^
+  // CHECK: {{^}}          ()[5]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-9]]:7-[[@LINE-9]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-10]]:11-[[@LINE-10]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-11]]:12-[[@LINE-11]]:12}:")[5]"
+
+  int [5] * a;
+  // expected-error@-1{{brackets go after the identifier}}
+  // CHECK: {{^}}  int [5] * a;
+  // CHECK: {{^}}      ~~~~   ^
+  // CHECK: {{^}}          (  )[5]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:11-[[@LINE-6]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:14-[[@LINE-7]]:14}:")[5]"
+
+  int *b[5] = a;  // expected-error{{}} a should not be corrected to type b
+
+  int (*c)[5] = a;  // a should be the same type as c
+}
+#endif
+
+// CHECK: 8 errors generated.
diff --git a/test/Parser/brackets.cpp b/test/Parser/brackets.cpp
new file mode 100644
index 0000000..f418c11
--- /dev/null
+++ b/test/Parser/brackets.cpp
@@ -0,0 +1,153 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -fixit %t -x c++ -DFIXIT
+// RUN: %clang_cc1 -fsyntax-only %t -x c++ -DFIXIT
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s -strict-whitespace
+
+void test1() {
+  int a[] = {0,1,1,2,3};
+  int []b = {0,1,4,9,16};
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int []b = {0,1,4,9,16};
+  // CHECK: {{^}}      ~~ ^
+  // CHECK: {{^}}         []
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:9}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:10-[[@LINE-6]]:10}:"[]"
+
+  int c = a[0];
+  int d = b[0];  // No undeclared identifer error here.
+
+  int *e = a;
+  int *f = b;  // No undeclared identifer error here.
+
+  int[1] g[2];
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int[1] g[2];
+  // CHECK: {{^}}     ~~~     ^
+  // CHECK: {{^}}             [1]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:6-[[@LINE-5]]:9}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:14-[[@LINE-6]]:14}:"[1]"
+}
+
+void test2() {
+  int [3] (*a) = 0;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [3] (*a) = 0;
+  // CHECK: {{^}}      ~~~~    ^
+  // CHECK: {{^}}              [3]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:15-[[@LINE-6]]:15}:"[3]"
+
+#ifndef FIXIT
+  // Make sure a is corrected to be like type y, instead of like type z.
+  int (*b)[3] = a;
+  int (*c[3]) = a;  // expected-error{{}}
+#endif
+}
+
+struct A {
+  static int [1][1]x;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  static int [1][1]x;
+  // CHECK: {{^}}             ~~~~~~ ^
+  // CHECK: {{^}}                    [1][1]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:14-[[@LINE-5]]:20}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:21-[[@LINE-6]]:21}:"[1][1]"
+};
+
+int [1][1]A::x = { {42} };
+// expected-error@-1{{brackets go after the unqualified-id}}
+// CHECK: {{^}}int [1][1]A::x = { {42} };
+// CHECK: {{^}}    ~~~~~~    ^
+// CHECK: {{^}}              [1][1]
+// CHECK: fix-it:{{.*}}:{[[@LINE-5]]:5-[[@LINE-5]]:11}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-6]]:15-[[@LINE-6]]:15}:"[1][1]"
+
+struct B { static int (*x)[5]; };
+int [5] *B::x = 0;
+// expected-error@-1{{brackets go after the unqualified-id}}
+// CHECK: {{^}}int [5] *B::x = 0;
+// CHECK: {{^}}    ~~~~     ^
+// CHECK: {{^}}        (    )[5]
+// CHECK: fix-it:{{.*}}:{[[@LINE-5]]:5-[[@LINE-5]]:9}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-6]]:9-[[@LINE-6]]:9}:"("
+// CHECK: fix-it:{{.*}}:{[[@LINE-7]]:14-[[@LINE-7]]:14}:")[5]"
+
+void test3() {
+  int [3] *a;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [3] *a;
+  // CHECK: {{^}}      ~~~~  ^
+  // CHECK: {{^}}          ( )[3]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:11-[[@LINE-6]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:13-[[@LINE-7]]:13}:")[3]"
+
+  int (*b)[3] = a;  // no error
+}
+
+void test4() {
+  int [2] a;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [2] a;
+  // CHECK: {{^}}      ~~~~ ^
+  // CHECK: {{^}}           [2]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:12-[[@LINE-6]]:12}:"[2]"
+
+  int [2] &b = a;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [2] &b = a;
+  // CHECK: {{^}}      ~~~~  ^
+  // CHECK: {{^}}          ( )[2]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:11-[[@LINE-6]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:13-[[@LINE-7]]:13}:")[2]"
+
+}
+
+namespace test5 {
+#ifndef FIXIT
+int [][][];
+// expected-error@-1{{expected unqualified-id}}
+// CHECK: {{^}}int [][][];
+// CHECK: {{^}}    ^
+
+struct C {
+  int [];
+  // expected-error@-1{{expected member name or ';' after declaration specifiers}}
+  // CHECK: {{^}}  int [];
+  // CHECK: {{^}}  ~~~ ^
+};
+
+#endif
+}
+
+namespace test6 {
+struct A {
+  static int arr[3];
+};
+int [3] ::test6::A::arr = {1,2,3};
+// expected-error@-1{{brackets go after the unqualified-id}}
+// CHECK: {{^}}int [3] ::test6::A::arr = {1,2,3};
+// CHECK: {{^}}    ~~~~               ^
+// CHECK: {{^}}                       [3]
+// CHECK: fix-it:{{.*}}:{[[@LINE-5]]:5-[[@LINE-5]]:9}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-6]]:24-[[@LINE-6]]:24}:"[3]"
+
+}
+
+namespace test7 {
+class A{};
+void test() {
+  int [3] A::*a;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [3] A::*a;
+  // CHECK: {{^}}      ~~~~     ^
+  // CHECK: {{^}}          (    )[3]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:11-[[@LINE-6]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:16-[[@LINE-7]]:16}:")[3]"
+}
+}
+// CHECK: 14 errors generated.
diff --git a/test/Parser/cuda-kernel-call-c++11.cu b/test/Parser/cuda-kernel-call-c++11.cu
new file mode 100644
index 0000000..8f833f7
--- /dev/null
+++ b/test/Parser/cuda-kernel-call-c++11.cu
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+template<typename> struct S {};
+template<typename> void f();
+
+
+void foo(void) {
+  // In C++11 mode, all of these are expected to parse correctly, and the CUDA
+  // language should not interfere with that.
+
+  // expected-no-diagnostics
+
+  S<S<S<int>>> s3;
+
+  S<S<S<S<int>>>> s4;
+
+  S<S<S<S<S<int>>>>> s5;
+
+  (void)(&f<S<S<int>>>==0);
+}
diff --git a/test/Parser/cuda-kernel-call.cu b/test/Parser/cuda-kernel-call.cu
index 92e46e3..1970c55 100644
--- a/test/Parser/cuda-kernel-call.cu
+++ b/test/Parser/cuda-kernel-call.cu
@@ -10,7 +10,8 @@
 
   foo<<<>>>();  // expected-error {{expected expression}}
 
-  S<S<S<int>>> s; // expected-error 2{{use '> >'}}
+  // The following two are parse errors because -std=c++11 is not enabled.
 
+  S<S<S<int>>> s; // expected-error 2{{use '> >'}}
   (void)(&f<S<S<int>>>==0); // expected-error 2{{use '> >'}}
 }
diff --git a/test/Parser/cxx-altivec.cpp b/test/Parser/cxx-altivec.cpp
index 27cab2c..565decc 100644
--- a/test/Parser/cxx-altivec.cpp
+++ b/test/Parser/cxx-altivec.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -faltivec -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -faltivec -fsyntax-only -verify -std=c++11 %s
 
 __vector char vv_c;
 __vector signed char vv_sc;
diff --git a/test/Parser/cxx-ambig-decl-expr-xfail.cpp b/test/Parser/cxx-ambig-decl-expr-xfail.cpp
index ac4accb..85c3468 100644
--- a/test/Parser/cxx-ambig-decl-expr-xfail.cpp
+++ b/test/Parser/cxx-ambig-decl-expr-xfail.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // XFAIL: *
+// FIXME: This is PR7655
+
 struct X { 
   template<typename T> X(T);
   X(int, int);
diff --git a/test/Parser/cxx-template-decl.cpp b/test/Parser/cxx-template-decl.cpp
index 8742900..8b2b120 100644
--- a/test/Parser/cxx-template-decl.cpp
+++ b/test/Parser/cxx-template-decl.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++1z %s
 
 
 
@@ -24,6 +25,11 @@
 template <template <typename> > struct Err2;       // expected-error {{template template parameter requires 'class' after the parameter list}}
 template <template <typename> Foo> struct Err3;    // expected-error {{template template parameter requires 'class' after the parameter list}}
 
+template <template <typename> typename Foo> struct Cxx1z;
+#if __cplusplus <= 201402L
+// expected-warning@-2 {{extension}}
+#endif
+
 // Template function declarations
 template <typename T> void foo();
 template <typename T, typename U> void foo();
diff --git a/test/Parser/cxx0x-member-initializers.cpp b/test/Parser/cxx0x-member-initializers.cpp
index 43e99b1..4d14394 100644
--- a/test/Parser/cxx0x-member-initializers.cpp
+++ b/test/Parser/cxx0x-member-initializers.cpp
@@ -37,3 +37,7 @@
   bool d1 = T1<int, T1<int, int>>::V < 3, d2;
   T1<int, int()> e = T1<int, int()>();
 };
+
+struct PR19993 {
+  static int n = delete; // expected-error {{only functions can have deleted definitions}}
+};
diff --git a/test/Parser/ms-if-exists.cpp b/test/Parser/ms-if-exists.cpp
new file mode 100644
index 0000000..79cc571
--- /dev/null
+++ b/test/Parser/ms-if-exists.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+class MayExist {
+private:
+  typedef int Type;
+};
+
+void test_if_exists_stmts() {
+  int b = 0;
+  __if_exists(MayExist::Type) {
+    b++;
+    b++;
+  }
+  __if_exists(MayExist::Type_not) {
+    this will not compile.
+  }
+  __if_not_exists(MayExist::Type) {
+    this will not compile.
+  }
+  __if_not_exists(MayExist::Type_not) {
+    b++;
+    b++;
+  }
+}
+
+int if_exists_creates_no_scope() {
+  __if_exists(MayExist::Type) {
+    int x;  // 'x' is declared in the parent scope.
+  }
+  __if_not_exists(MayExist::Type_not) {
+    x++;
+  }
+  return x;
+}
+
+__if_exists(MayExist::Type) {
+  int var23;
+}
+
+__if_exists(MayExist::Type_not) {
+  this will not compile.
+}
+
+__if_not_exists(MayExist::Type) {
+  this will not compile.
+}
+
+__if_not_exists(MayExist::Type_not) {
+  int var244;
+}
+
+void test_if_exists_init_list() {
+
+  int array1[] = {
+    0,
+    __if_exists(MayExist::Type) {2, }
+    3
+  };
+
+  int array2[] = {
+    0,
+    __if_exists(MayExist::Type_not) { this will not compile }
+    3
+  };
+
+  int array3[] = {
+    0,
+    __if_not_exists(MayExist::Type_not) {2, }
+    3
+  };
+
+  int array4[] = {
+    0,
+    __if_not_exists(MayExist::Type) { this will not compile }
+    3
+  };
+
+}
+
+
+class IfExistsClassScope {
+  __if_exists(MayExist::Type) {
+    // __if_exists, __if_not_exists can nest
+    __if_not_exists(MayExist::Type_not) {
+      int var123;
+    }
+    int var23;
+  }
+
+  __if_exists(MayExist::Type_not) {
+   this will not compile.
+  }
+
+  __if_not_exists(MayExist::Type) {
+   this will not compile.
+  }
+
+  __if_not_exists(MayExist::Type_not) {
+    int var244;
+  }
+};
+
+void test_nested_if_exists() {
+  __if_exists(MayExist::Type) {
+    int x = 42;
+    __if_not_exists(MayExist::Type_not) {
+      x++;
+    }
+  }
+}
+
+void test_attribute_on_if_exists() {
+  [[clang::fallthrough]] // expected-error {{an attribute list cannot appear here}}
+  __if_exists(MayExist::Type) {
+    int x;
+  }
+}
diff --git a/test/Parser/ms-inline-asm-nested-braces.c b/test/Parser/ms-inline-asm-nested-braces.c
new file mode 100644
index 0000000..58b055b
--- /dev/null
+++ b/test/Parser/ms-inline-asm-nested-braces.c
@@ -0,0 +1,9 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -verify -fasm-blocks
+
+int t_fail() { // expected-note {{to match this}}
+  __asm
+  { // expected-note {{to match this}}
+    { // expected-note {{to match this}}
+      {
+      } // expected-error 3 {{expected}}
diff --git a/test/Parser/ms-inline-asm.c b/test/Parser/ms-inline-asm.c
index a9c15cf..564f008 100644
--- a/test/Parser/ms-inline-asm.c
+++ b/test/Parser/ms-inline-asm.c
@@ -34,6 +34,17 @@
 void t9() {
   __asm nop __asm nop ; __asm nop
 }
+void t10() {
+  __asm {
+    mov eax, 0
+    __asm {
+      mov eax, 1
+      {
+        mov eax, 2
+      }
+    }
+  }
+}
 int t_fail() { // expected-note {{to match this}}
   __asm 
   __asm { // expected-error 3 {{expected}} expected-note {{to match this}}
diff --git a/test/Parser/pragma-loop.cpp b/test/Parser/pragma-loop.cpp
new file mode 100644
index 0000000..fad4feb
--- /dev/null
+++ b/test/Parser/pragma-loop.cpp
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+void test(int *List, int Length) {
+  int i = 0;
+
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave(enable)
+#pragma clang loop unroll(enable)
+  while (i + 1 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop vectorize_width(4)
+#pragma clang loop interleave_count(8)
+#pragma clang loop unroll_count(16)
+  while (i < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop vectorize(disable)
+#pragma clang loop interleave(disable)
+#pragma clang loop unroll(disable)
+  while (i - 1 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop vectorize_width(4) interleave_count(8) unroll_count(16)
+  while (i - 2 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop interleave_count(16)
+  while (i - 3 < Length) {
+    List[i] = i;
+  }
+
+  int VList[Length];
+#pragma clang loop vectorize(disable) interleave(disable) unroll(disable)
+  for (int j : VList) {
+    VList[j] = List[j];
+  }
+
+/* expected-error {{expected '('}} */ #pragma clang loop vectorize
+/* expected-error {{expected '('}} */ #pragma clang loop interleave
+/* expected-error {{expected '('}} */ #pragma clang loop unroll
+
+/* expected-error {{expected ')'}} */ #pragma clang loop vectorize(enable
+/* expected-error {{expected ')'}} */ #pragma clang loop interleave(enable
+/* expected-error {{expected ')'}} */ #pragma clang loop unroll(enable
+
+/* expected-error {{expected ')'}} */ #pragma clang loop vectorize_width(4
+/* expected-error {{expected ')'}} */ #pragma clang loop interleave_count(4
+/* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4
+
+/* expected-error {{missing argument to loop pragma 'vectorize'}} */ #pragma clang loop vectorize()
+/* expected-error {{missing argument to loop pragma 'interleave_count'}} */ #pragma clang loop interleave_count()
+/* expected-error {{missing argument to loop pragma 'unroll'}} */ #pragma clang loop unroll()
+
+/* expected-error {{missing option}} */ #pragma clang loop
+/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword
+/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword(enable)
+/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop vectorize(enable) badkeyword(4)
+/* expected-warning {{extra tokens at end of '#pragma clang loop'}} */ #pragma clang loop vectorize(enable) ,
+
+  while (i-4 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(0)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(0)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(0)
+  while (i-5 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(3000000000)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(3000000000)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(3000000000)
+  while (i-6 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(badvalue)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(badvalue)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(badvalue)
+  while (i-6 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(badidentifier)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(badidentifier)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(badidentifier)
+  while (i-7 < Length) {
+    List[i] = i;
+  }
+
+// PR20069 - Loop pragma arguments that are not identifiers or numeric
+// constants crash FE.
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(()
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(*)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(=)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(^)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(/)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(==)
+  while (i-8 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop vectorize(enable)
+/* expected-error {{expected a for, while, or do-while loop to follow the '#pragma clang loop' directive}} */ int j = Length;
+  List[0] = List[1];
+
+  while (j-1 < Length) {
+    List[j] = j;
+  }
+
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// processed in reverse. Consequently, the errors occur on the first of pragma
+// of the next three tests rather than the last, and the order of the kinds
+// is also reversed.
+
+/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize_width(4)
+#pragma clang loop vectorize(disable)
+/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave_count(4)
+#pragma clang loop interleave(disable)
+/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
+#pragma clang loop unroll(disable)
+  while (i-8 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{duplicate directives 'vectorize(disable)' and 'vectorize(enable)'}} */ #pragma clang loop vectorize(enable)
+#pragma clang loop vectorize(disable)
+/* expected-error {{duplicate directives 'interleave(disable)' and 'interleave(enable)'}} */ #pragma clang loop interleave(enable)
+#pragma clang loop interleave(disable)
+/* expected-error {{duplicate directives 'unroll(disable)' and 'unroll(enable)'}} */ #pragma clang loop unroll(enable)
+#pragma clang loop unroll(disable)
+  while (i-9 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize(disable)
+#pragma clang loop vectorize_width(4)
+/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave(disable)
+#pragma clang loop interleave_count(4)
+/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll(disable)
+#pragma clang loop unroll_count(4)
+  while (i-10 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{duplicate directives 'vectorize_width(4)' and 'vectorize_width(8)'}} */ #pragma clang loop vectorize_width(8)
+#pragma clang loop vectorize_width(4)
+/* expected-error {{duplicate directives 'interleave_count(4)' and 'interleave_count(8)'}} */ #pragma clang loop interleave_count(8)
+#pragma clang loop interleave_count(4)
+/* expected-error {{duplicate directives 'unroll_count(4)' and 'unroll_count(8)'}} */ #pragma clang loop unroll_count(8)
+#pragma clang loop unroll_count(4)
+  while (i-11 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop interleave(enable)
+/* expected-error {{expected statement}} */ }
diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c
index bd5e4d8..4dc03e0 100644
--- a/test/Preprocessor/aarch64-target-features.c
+++ b/test/Preprocessor/aarch64-target-features.c
@@ -49,3 +49,13 @@
 // RUN: %clang -target arm64-none-linux-gnu -mfpu=neon -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NEON %s
 // CHECK-NEON: __ARM_NEON 1
 // CHECK-NEON: __ARM_NEON_FP 0xe
+
+// RUN: %clang -target aarch64-none-linux-gnu -mcpu=cortex-a53 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEATURE %s
+// RUN: %clang -target aarch64-none-linux-gnu -mcpu=cortex-a57 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEATURE %s
+// RUN: %clang -target aarch64-none-linux-gnu -mcpu=cyclone -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEATURE %s
+// CHECK-FEATURE: __ARM_FEATURE_CRC32 1
+// CHECK-FEATURE: __ARM_FEATURE_CRYPTO 1
+// CHECK-FEATURE: __ARM_NEON 1
+// CHECK-FEATURE: __ARM_NEON_FP 0xe
+
+
diff --git a/test/Preprocessor/arm-acle-6.4.c b/test/Preprocessor/arm-acle-6.4.c
new file mode 100644
index 0000000..a656f76
--- /dev/null
+++ b/test/Preprocessor/arm-acle-6.4.c
@@ -0,0 +1,40 @@
+// RUN: %clang -target arm-eabi -mcpu=cortex-m0 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-CORTEX-M0
+
+// CHECK-CORTEX-M0: __ARM_32BIT_STATE 1
+// CHECK-CORTEX-M0: __ARM_ARCH 6
+// CHECK-CORTEX-M0-NOT: __ARM_ARCH_ISA_ARM
+// CHECK-CORTEX-M0: __ARM_ARCH_ISA_THUMB 1
+// CHECK-CORTEX-M0: __ARM_ARCH_PROFILE 'M'
+
+// RUN: %clang -target arm-eabi -mcpu=arm810 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-ARM810
+
+// CHECK-ARM810: __ARM_32BIT_STATE 1
+// CHECK-ARM810: __ARM_ARCH 4
+// CHECK-ARM810: __ARM_ARCH_ISA_ARM 1
+// CHECK-ARM810-NOT: __ARM_ARCH_ISA_THUMB
+// CHECK-ARM810-NOT: __ARM_ARCH_PROFILE
+
+// RUN: %clang -target arm-eabi -mcpu=arm7tdmi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-ARM7TDMI
+
+// CHECK-ARM7TDMI: __ARM_32BIT_STATE 1
+// CHECK-ARM7TDMI: __ARM_ARCH 4
+// CHECK-ARM7TDMI: __ARM_ARCH_ISA_ARM 1
+// CHECK-ARM7TDMI: __ARM_ARCH_ISA_THUMB 1
+// CHECK-ARM7TDMI-NOT: __ARM_ARCH_PROFILE
+
+// RUN: %clang -target arm-eabi -mcpu=cortex-a7 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-CORTEX-A7
+
+// CHECK-CORTEX-A7: __ARM_32BIT_STATE 1
+// CHECK-CORTEX-A7: __ARM_ARCH 7
+// CHECK-CORTEX-A7: __ARM_ARCH_ISA_ARM 1
+// CHECK-CORTEX-A7: __ARM_ARCH_ISA_THUMB 2
+// CHECK-CORTEX-A7: __ARM_ARCH_PROFILE 'A'
+
+// RUN: %clang -target arm-eabi -mcpu=cortex-r4 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-CORTEX-R4
+
+// CHECK-CORTEX-R4: __ARM_32BIT_STATE 1
+// CHECK-CORTEX-R4: __ARM_ARCH 7
+// CHECK-CORTEX-R4: __ARM_ARCH_ISA_ARM 1
+// CHECK-CORTEX-R4: __ARM_ARCH_ISA_THUMB 2
+// CHECK-CORTEX-R4: __ARM_ARCH_PROFILE 'R'
+
diff --git a/test/Preprocessor/arm-target-features.c b/test/Preprocessor/arm-target-features.c
index 9db29a6..08fe29a 100644
--- a/test/Preprocessor/arm-target-features.c
+++ b/test/Preprocessor/arm-target-features.c
@@ -148,7 +148,7 @@
 // RUN: %clang -target armv7 -mthumb -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck --check-prefix=A5 %s
 // A5:#define __ARM_ARCH 7
 // A5:#define __ARM_ARCH_7A__ 1
-// A5:#define __ARM_ARCH_PROFILE A
+// A5:#define __ARM_ARCH_PROFILE 'A'
 
 // Test whether predefines are as expected when targeting cortex-a7.
 // RUN: %clang -target armv7 -mcpu=cortex-a7 -x c -E -dM %s -o - | FileCheck --check-prefix=A7 %s
@@ -156,7 +156,7 @@
 // A7:#define __ARM_ARCH 7
 // A7:#define __ARM_ARCH_7A__ 1
 // A7:#define __ARM_ARCH_EXT_IDIV__ 1
-// A7:#define __ARM_ARCH_PROFILE A
+// A7:#define __ARM_ARCH_PROFILE 'A'
 
 // Test whether predefines are as expected when targeting cortex-a8.
 // RUN: %clang -target armv7 -mcpu=cortex-a8 -x c -E -dM %s -o - | FileCheck --check-prefix=A8-ARM %s
@@ -190,7 +190,7 @@
 // A12:#define __ARM_ARCH 7
 // A12:#define __ARM_ARCH_7A__ 1
 // A12:#define __ARM_ARCH_EXT_IDIV__ 1
-// A12:#define __ARM_ARCH_PROFILE A
+// A12:#define __ARM_ARCH_PROFILE 'A'
 
 // Test whether predefines are as expected when targeting cortex-a15.
 // RUN: %clang -target armv7 -mcpu=cortex-a15 -x c -E -dM %s -o - | FileCheck --check-prefix=A15-ARM %s
diff --git a/test/Preprocessor/cxx_oper_keyword.cpp b/test/Preprocessor/cxx_oper_keyword.cpp
index 03e2a66..89a094d 100644
--- a/test/Preprocessor/cxx_oper_keyword.cpp
+++ b/test/Preprocessor/cxx_oper_keyword.cpp
@@ -11,12 +11,21 @@
 // Not valid in C++ unless -fno-operator-names is passed:
 
 #ifdef OPERATOR_NAMES
-//expected-error@+2 {{C++ operator 'and' (aka '&&') cannot be used as a macro name}}
+//expected-error@+2 {{C++ operator 'and' (aka '&&') used as a macro name}}
 #endif
 #define and foo
 
 #ifdef OPERATOR_NAMES
-//expected-error@+2 {{C++ operator 'xor' (aka '^') cannot be used as a macro name}}
+//expected-error@+2 {{C++ operator 'xor' (aka '^') used as a macro name}}
 #endif
 #if defined xor
 #endif
+
+// For error recovery we continue as though the identifier was a macro name regardless of -fno-operator-names.
+#ifdef OPERATOR_NAMES
+//expected-error@+3 {{C++ operator 'and' (aka '&&') used as a macro name}}
+#endif
+//expected-warning@+2 {{and is defined}}
+#ifdef and
+#warning and is defined
+#endif
diff --git a/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp b/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp
index dcf6908..8e1351e 100644
--- a/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp
+++ b/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -E -fms-compatibility
+// RUN: %clang_cc1 %s -E -verify -fms-extensions
+// expected-no-diagnostics
 
 bool f() {
   // Check that operators still work before redefining them.
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 358612f..3f15502 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -9,6 +9,16 @@
 // BLOCKS:#define __block __attribute__((__blocks__(byref)))
 //
 //
+// RUN: %clang_cc1 -x c++ -std=c++1z -E -dM < /dev/null | FileCheck -check-prefix CXX1Z %s
+//
+// CXX1Z:#define __GNUG__
+// CXX1Z:#define __GXX_EXPERIMENTAL_CXX0X__ 1
+// CXX1Z:#define __GXX_RTTI 1
+// CXX1Z:#define __GXX_WEAK__ 1
+// CXX1Z:#define __cplusplus 201406L
+// CXX1Z:#define __private_extern__ extern
+//
+//
 // RUN: %clang_cc1 -x c++ -std=c++1y -E -dM < /dev/null | FileCheck -check-prefix CXX1Y %s
 //
 // CXX1Y:#define __GNUG__
@@ -85,6 +95,14 @@
 // FREESTANDING:#define __STDC_HOSTED__ 0
 //
 //
+// RUN: %clang_cc1 -x c++ -std=gnu++1z -E -dM < /dev/null | FileCheck -check-prefix GXX1Z %s
+//
+// GXX1Z:#define __GNUG__
+// GXX1Z:#define __GXX_WEAK__ 1
+// GXX1Z:#define __cplusplus 201406L
+// GXX1Z:#define __private_extern__ extern
+//
+//
 // RUN: %clang_cc1 -x c++ -std=gnu++1y -E -dM < /dev/null | FileCheck -check-prefix GXX1Y %s
 //
 // GXX1Y:#define __GNUG__
@@ -256,16 +274,37 @@
 // AARCH64:#define __FLT_MIN_EXP__ (-125)
 // AARCH64:#define __FLT_MIN__ 1.17549435e-38F
 // AARCH64:#define __FLT_RADIX__ 2
+// AARCH64:#define __INT16_MAX__ 32767
 // AARCH64:#define __INT16_TYPE__ short
+// AARCH64:#define __INT32_MAX__ 2147483647
 // AARCH64:#define __INT32_TYPE__ int
 // AARCH64:#define __INT64_C_SUFFIX__ L
+// AARCH64:#define __INT64_MAX__ 9223372036854775807L
 // AARCH64:#define __INT64_TYPE__ long int
+// AARCH64:#define __INT8_MAX__ 127
 // AARCH64:#define __INT8_TYPE__ char
 // AARCH64:#define __INTMAX_MAX__ 9223372036854775807L
 // AARCH64:#define __INTMAX_TYPE__ long int
 // AARCH64:#define __INTMAX_WIDTH__ 64
+// AARCH64:#define __INTPTR_MAX__ 9223372036854775807L
 // AARCH64:#define __INTPTR_TYPE__ long int
 // AARCH64:#define __INTPTR_WIDTH__ 64
+// AARCH64:#define __INT_FAST16_MAX__ 32767
+// AARCH64:#define __INT_FAST16_TYPE__ short
+// AARCH64:#define __INT_FAST32_MAX__ 2147483647
+// AARCH64:#define __INT_FAST32_TYPE__ int
+// AARCH64:#define __INT_FAST64_MAX__ 9223372036854775807L
+// AARCH64:#define __INT_FAST64_TYPE__ long int
+// AARCH64:#define __INT_FAST8_MAX__ 127
+// AARCH64:#define __INT_FAST8_TYPE__ char
+// AARCH64:#define __INT_LEAST16_MAX__ 32767
+// AARCH64:#define __INT_LEAST16_TYPE__ short
+// AARCH64:#define __INT_LEAST32_MAX__ 2147483647
+// AARCH64:#define __INT_LEAST32_TYPE__ int
+// AARCH64:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// AARCH64:#define __INT_LEAST64_TYPE__ long int
+// AARCH64:#define __INT_LEAST8_MAX__ 127
+// AARCH64:#define __INT_LEAST8_TYPE__ char
 // AARCH64:#define __INT_MAX__ 2147483647
 // AARCH64:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // AARCH64:#define __LDBL_DIG__ 33
@@ -305,7 +344,40 @@
 // AARCH64:#define __SIZE_MAX__ 18446744073709551615UL
 // AARCH64:#define __SIZE_TYPE__ long unsigned int
 // AARCH64:#define __SIZE_WIDTH__ 64
+// AARCH64:#define __UINT16_C_SUFFIX__ U
+// AARCH64:#define __UINT16_MAX__ 65535U
+// AARCH64:#define __UINT16_TYPE__ unsigned short
+// AARCH64:#define __UINT32_C_SUFFIX__ U
+// AARCH64:#define __UINT32_MAX__ 4294967295U
+// AARCH64:#define __UINT32_TYPE__ unsigned int
+// AARCH64:#define __UINT64_C_SUFFIX__ UL
+// AARCH64:#define __UINT64_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINT64_TYPE__ long unsigned int
+// AARCH64:#define __UINT8_C_SUFFIX__ U
+// AARCH64:#define __UINT8_MAX__ 255U
+// AARCH64:#define __UINT8_TYPE__ unsigned char
+// AARCH64:#define __UINTMAX_MAX__ 18446744073709551615UL
 // AARCH64:#define __UINTMAX_TYPE__ long unsigned int
+// AARCH64:#define __UINTMAX_WIDTH__ 64
+// AARCH64:#define __UINTPTR_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINTPTR_TYPE__ long unsigned int
+// AARCH64:#define __UINTPTR_WIDTH__ 64
+// AARCH64:#define __UINT_FAST16_MAX__ 65535U
+// AARCH64:#define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64:#define __UINT_FAST32_MAX__ 4294967295U
+// AARCH64:#define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINT_FAST64_TYPE__ long unsigned int
+// AARCH64:#define __UINT_FAST8_MAX__ 255U
+// AARCH64:#define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64:#define __UINT_LEAST16_MAX__ 65535U
+// AARCH64:#define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64:#define __UINT_LEAST32_MAX__ 4294967295U
+// AARCH64:#define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINT_LEAST64_TYPE__ long unsigned int
+// AARCH64:#define __UINT_LEAST8_MAX__ 255U
+// AARCH64:#define __UINT_LEAST8_TYPE__ unsigned char
 // AARCH64:#define __USER_LABEL_PREFIX__ _
 // AARCH64:#define __WCHAR_MAX__ 4294967295U
 // AARCH64:#define __WCHAR_TYPE__ unsigned int
@@ -359,16 +431,37 @@
 // AARCH64-BE:#define __FLT_MIN_EXP__ (-125)
 // AARCH64-BE:#define __FLT_MIN__ 1.17549435e-38F
 // AARCH64-BE:#define __FLT_RADIX__ 2
+// AARCH64-BE:#define __INT16_MAX__ 32767
 // AARCH64-BE:#define __INT16_TYPE__ short
+// AARCH64-BE:#define __INT32_MAX__ 2147483647
 // AARCH64-BE:#define __INT32_TYPE__ int
 // AARCH64-BE:#define __INT64_C_SUFFIX__ L
+// AARCH64-BE:#define __INT64_MAX__ 9223372036854775807L
 // AARCH64-BE:#define __INT64_TYPE__ long int
+// AARCH64-BE:#define __INT8_MAX__ 127
 // AARCH64-BE:#define __INT8_TYPE__ char
 // AARCH64-BE:#define __INTMAX_MAX__ 9223372036854775807L
 // AARCH64-BE:#define __INTMAX_TYPE__ long int
 // AARCH64-BE:#define __INTMAX_WIDTH__ 64
+// AARCH64-BE:#define __INTPTR_MAX__ 9223372036854775807L
 // AARCH64-BE:#define __INTPTR_TYPE__ long int
 // AARCH64-BE:#define __INTPTR_WIDTH__ 64
+// AARCH64-BE:#define __INT_FAST16_MAX__ 32767
+// AARCH64-BE:#define __INT_FAST16_TYPE__ short
+// AARCH64-BE:#define __INT_FAST32_MAX__ 2147483647
+// AARCH64-BE:#define __INT_FAST32_TYPE__ int
+// AARCH64-BE:#define __INT_FAST64_MAX__ 9223372036854775807L
+// AARCH64-BE:#define __INT_FAST64_TYPE__ long int
+// AARCH64-BE:#define __INT_FAST8_MAX__ 127
+// AARCH64-BE:#define __INT_FAST8_TYPE__ char
+// AARCH64-BE:#define __INT_LEAST16_MAX__ 32767
+// AARCH64-BE:#define __INT_LEAST16_TYPE__ short
+// AARCH64-BE:#define __INT_LEAST32_MAX__ 2147483647
+// AARCH64-BE:#define __INT_LEAST32_TYPE__ int
+// AARCH64-BE:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// AARCH64-BE:#define __INT_LEAST64_TYPE__ long int
+// AARCH64-BE:#define __INT_LEAST8_MAX__ 127
+// AARCH64-BE:#define __INT_LEAST8_TYPE__ char
 // AARCH64-BE:#define __INT_MAX__ 2147483647
 // AARCH64-BE:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // AARCH64-BE:#define __LDBL_DIG__ 33
@@ -408,7 +501,40 @@
 // AARCH64-BE:#define __SIZE_MAX__ 18446744073709551615UL
 // AARCH64-BE:#define __SIZE_TYPE__ long unsigned int
 // AARCH64-BE:#define __SIZE_WIDTH__ 64
+// AARCH64-BE:#define __UINT16_C_SUFFIX__ U
+// AARCH64-BE:#define __UINT16_MAX__ 65535U
+// AARCH64-BE:#define __UINT16_TYPE__ unsigned short
+// AARCH64-BE:#define __UINT32_C_SUFFIX__ U
+// AARCH64-BE:#define __UINT32_MAX__ 4294967295U
+// AARCH64-BE:#define __UINT32_TYPE__ unsigned int
+// AARCH64-BE:#define __UINT64_C_SUFFIX__ UL
+// AARCH64-BE:#define __UINT64_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINT64_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINT8_C_SUFFIX__ U
+// AARCH64-BE:#define __UINT8_MAX__ 255U
+// AARCH64-BE:#define __UINT8_TYPE__ unsigned char
+// AARCH64-BE:#define __UINTMAX_MAX__ 18446744073709551615UL
 // AARCH64-BE:#define __UINTMAX_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINTMAX_WIDTH__ 64
+// AARCH64-BE:#define __UINTPTR_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINTPTR_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINTPTR_WIDTH__ 64
+// AARCH64-BE:#define __UINT_FAST16_MAX__ 65535U
+// AARCH64-BE:#define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64-BE:#define __UINT_FAST32_MAX__ 4294967295U
+// AARCH64-BE:#define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64-BE:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINT_FAST64_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINT_FAST8_MAX__ 255U
+// AARCH64-BE:#define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64-BE:#define __UINT_LEAST16_MAX__ 65535U
+// AARCH64-BE:#define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64-BE:#define __UINT_LEAST32_MAX__ 4294967295U
+// AARCH64-BE:#define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64-BE:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINT_LEAST64_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINT_LEAST8_MAX__ 255U
+// AARCH64-BE:#define __UINT_LEAST8_TYPE__ unsigned char
 // AARCH64-BE:#define __USER_LABEL_PREFIX__ _
 // AARCH64-BE:#define __WCHAR_MAX__ 4294967295U
 // AARCH64-BE:#define __WCHAR_TYPE__ unsigned int
@@ -462,16 +588,37 @@
 // AARCH64-NETBSD:#define __FLT_MIN_EXP__ (-125)
 // AARCH64-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
 // AARCH64-NETBSD:#define __FLT_RADIX__ 2
+// AARCH64-NETBSD:#define __INT16_MAX__ 32767
 // AARCH64-NETBSD:#define __INT16_TYPE__ short
+// AARCH64-NETBSD:#define __INT32_MAX__ 2147483647
 // AARCH64-NETBSD:#define __INT32_TYPE__ int
 // AARCH64-NETBSD:#define __INT64_C_SUFFIX__ LL
+// AARCH64-NETBSD:#define __INT64_MAX__ 9223372036854775807L
 // AARCH64-NETBSD:#define __INT64_TYPE__ long long int
+// AARCH64-NETBSD:#define __INT8_MAX__ 127
 // AARCH64-NETBSD:#define __INT8_TYPE__ char
 // AARCH64-NETBSD:#define __INTMAX_MAX__ 9223372036854775807LL
 // AARCH64-NETBSD:#define __INTMAX_TYPE__ long long int
 // AARCH64-NETBSD:#define __INTMAX_WIDTH__ 64
+// AARCH64-NETBSD:#define __INTPTR_MAX__ 9223372036854775807L
 // AARCH64-NETBSD:#define __INTPTR_TYPE__ long int
 // AARCH64-NETBSD:#define __INTPTR_WIDTH__ 64
+// AARCH64-NETBSD:#define __INT_FAST16_MAX__ 32767
+// AARCH64-NETBSD:#define __INT_FAST16_TYPE__ short
+// AARCH64-NETBSD:#define __INT_FAST32_MAX__ 2147483647
+// AARCH64-NETBSD:#define __INT_FAST32_TYPE__ int
+// AARCH64-NETBSD:#define __INT_FAST64_MAX__ 9223372036854775807L
+// AARCH64-NETBSD:#define __INT_FAST64_TYPE__ long int
+// AARCH64-NETBSD:#define __INT_FAST8_MAX__ 127
+// AARCH64-NETBSD:#define __INT_FAST8_TYPE__ char
+// AARCH64-NETBSD:#define __INT_LEAST16_MAX__ 32767
+// AARCH64-NETBSD:#define __INT_LEAST16_TYPE__ short
+// AARCH64-NETBSD:#define __INT_LEAST32_MAX__ 2147483647
+// AARCH64-NETBSD:#define __INT_LEAST32_TYPE__ int
+// AARCH64-NETBSD:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// AARCH64-NETBSD:#define __INT_LEAST64_TYPE__ long int
+// AARCH64-NETBSD:#define __INT_LEAST8_MAX__ 127
+// AARCH64-NETBSD:#define __INT_LEAST8_TYPE__ char
 // AARCH64-NETBSD:#define __INT_MAX__ 2147483647
 // AARCH64-NETBSD:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // AARCH64-NETBSD:#define __LDBL_DIG__ 33
@@ -512,7 +659,40 @@
 // AARCH64-NETBSD:#define __SIZE_MAX__ 18446744073709551615UL
 // AARCH64-NETBSD:#define __SIZE_TYPE__ long unsigned int
 // AARCH64-NETBSD:#define __SIZE_WIDTH__ 64
+// AARCH64-NETBSD:#define __UINT16_C_SUFFIX__ U
+// AARCH64-NETBSD:#define __UINT16_MAX__ 65535U
+// AARCH64-NETBSD:#define __UINT16_TYPE__ unsigned short
+// AARCH64-NETBSD:#define __UINT32_C_SUFFIX__ U
+// AARCH64-NETBSD:#define __UINT32_MAX__ 4294967295U
+// AARCH64-NETBSD:#define __UINT32_TYPE__ unsigned int
+// AARCH64-NETBSD:#define __UINT64_C_SUFFIX__ UL
+// AARCH64-NETBSD:#define __UINT64_MAX__ 18446744073709551615UL
+// AARCH64-NETBSD:#define __UINT64_TYPE__ long unsigned int
+// AARCH64-NETBSD:#define __UINT8_C_SUFFIX__ U
+// AARCH64-NETBSD:#define __UINT8_MAX__ 255U
+// AARCH64-NETBSD:#define __UINT8_TYPE__ unsigned char
+// AARCH64-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // AARCH64-NETBSD:#define __UINTMAX_TYPE__ long long unsigned int
+// AARCH64-NETBSD:#define __UINTMAX_WIDTH__ 64
+// AARCH64-NETBSD:#define __UINTPTR_MAX__ 18446744073709551615UL
+// AARCH64-NETBSD:#define __UINTPTR_TYPE__ long unsigned int
+// AARCH64-NETBSD:#define __UINTPTR_WIDTH__ 64
+// AARCH64-NETBSD:#define __UINT_FAST16_MAX__ 65535U
+// AARCH64-NETBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64-NETBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// AARCH64-NETBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64-NETBSD:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// AARCH64-NETBSD:#define __UINT_FAST64_TYPE__ long unsigned int
+// AARCH64-NETBSD:#define __UINT_FAST8_MAX__ 255U
+// AARCH64-NETBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64-NETBSD:#define __UINT_LEAST16_MAX__ 65535U
+// AARCH64-NETBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64-NETBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// AARCH64-NETBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64-NETBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// AARCH64-NETBSD:#define __UINT_LEAST64_TYPE__ long unsigned int
+// AARCH64-NETBSD:#define __UINT_LEAST8_MAX__ 255U
+// AARCH64-NETBSD:#define __UINT_LEAST8_TYPE__ unsigned char
 // AARCH64-NETBSD:#define __USER_LABEL_PREFIX__
 // AARCH64-NETBSD:#define __WCHAR_MAX__ 2147483647
 // AARCH64-NETBSD:#define __WCHAR_TYPE__ int
@@ -562,16 +742,37 @@
 // ARM:#define __FLT_MIN_EXP__ (-125)
 // ARM:#define __FLT_MIN__ 1.17549435e-38F
 // ARM:#define __FLT_RADIX__ 2
+// ARM:#define __INT16_MAX__ 32767
 // ARM:#define __INT16_TYPE__ short
+// ARM:#define __INT32_MAX__ 2147483647
 // ARM:#define __INT32_TYPE__ int
 // ARM:#define __INT64_C_SUFFIX__ LL
+// ARM:#define __INT64_MAX__ 9223372036854775807LL
 // ARM:#define __INT64_TYPE__ long long int
+// ARM:#define __INT8_MAX__ 127
 // ARM:#define __INT8_TYPE__ char
 // ARM:#define __INTMAX_MAX__ 9223372036854775807LL
 // ARM:#define __INTMAX_TYPE__ long long int
 // ARM:#define __INTMAX_WIDTH__ 64
+// ARM:#define __INTPTR_MAX__ 2147483647L
 // ARM:#define __INTPTR_TYPE__ long int
 // ARM:#define __INTPTR_WIDTH__ 32
+// ARM:#define __INT_FAST16_MAX__ 32767
+// ARM:#define __INT_FAST16_TYPE__ short
+// ARM:#define __INT_FAST32_MAX__ 2147483647
+// ARM:#define __INT_FAST32_TYPE__ int
+// ARM:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARM:#define __INT_FAST64_TYPE__ long long int
+// ARM:#define __INT_FAST8_MAX__ 127
+// ARM:#define __INT_FAST8_TYPE__ char
+// ARM:#define __INT_LEAST16_MAX__ 32767
+// ARM:#define __INT_LEAST16_TYPE__ short
+// ARM:#define __INT_LEAST32_MAX__ 2147483647
+// ARM:#define __INT_LEAST32_TYPE__ int
+// ARM:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARM:#define __INT_LEAST64_TYPE__ long long int
+// ARM:#define __INT_LEAST8_MAX__ 127
+// ARM:#define __INT_LEAST8_TYPE__ char
 // ARM:#define __INT_MAX__ 2147483647
 // ARM:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // ARM:#define __LDBL_DIG__ 15
@@ -613,7 +814,40 @@
 // ARM:#define __SIZE_TYPE__ unsigned int
 // ARM:#define __SIZE_WIDTH__ 32
 // ARM:#define __THUMB_INTERWORK__ 1
+// ARM:#define __UINT16_C_SUFFIX__ U
+// ARM:#define __UINT16_MAX__ 65535U
+// ARM:#define __UINT16_TYPE__ unsigned short
+// ARM:#define __UINT32_C_SUFFIX__ U
+// ARM:#define __UINT32_MAX__ 4294967295U
+// ARM:#define __UINT32_TYPE__ unsigned int
+// ARM:#define __UINT64_C_SUFFIX__ ULL
+// ARM:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARM:#define __UINT64_TYPE__ long long unsigned int
+// ARM:#define __UINT8_C_SUFFIX__ U
+// ARM:#define __UINT8_MAX__ 255U
+// ARM:#define __UINT8_TYPE__ unsigned char
+// ARM:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // ARM:#define __UINTMAX_TYPE__ long long unsigned int
+// ARM:#define __UINTMAX_WIDTH__ 64
+// ARM:#define __UINTPTR_MAX__ 4294967295U
+// ARM:#define __UINTPTR_TYPE__ unsigned int
+// ARM:#define __UINTPTR_WIDTH__ 32
+// ARM:#define __UINT_FAST16_MAX__ 65535U
+// ARM:#define __UINT_FAST16_TYPE__ unsigned short
+// ARM:#define __UINT_FAST32_MAX__ 4294967295U
+// ARM:#define __UINT_FAST32_TYPE__ unsigned int
+// ARM:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARM:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARM:#define __UINT_FAST8_MAX__ 255U
+// ARM:#define __UINT_FAST8_TYPE__ unsigned char
+// ARM:#define __UINT_LEAST16_MAX__ 65535U
+// ARM:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARM:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARM:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARM:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARM:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARM:#define __UINT_LEAST8_MAX__ 255U
+// ARM:#define __UINT_LEAST8_TYPE__ unsigned char
 // ARM:#define __USER_LABEL_PREFIX__ _
 // ARM:#define __WCHAR_MAX__ 4294967295U
 // ARM:#define __WCHAR_TYPE__ unsigned int
@@ -665,16 +899,37 @@
 // ARM-BE:#define __FLT_MIN_EXP__ (-125)
 // ARM-BE:#define __FLT_MIN__ 1.17549435e-38F
 // ARM-BE:#define __FLT_RADIX__ 2
+// ARM-BE:#define __INT16_MAX__ 32767
 // ARM-BE:#define __INT16_TYPE__ short
+// ARM-BE:#define __INT32_MAX__ 2147483647
 // ARM-BE:#define __INT32_TYPE__ int
 // ARM-BE:#define __INT64_C_SUFFIX__ LL
+// ARM-BE:#define __INT64_MAX__ 9223372036854775807LL
 // ARM-BE:#define __INT64_TYPE__ long long int
+// ARM-BE:#define __INT8_MAX__ 127
 // ARM-BE:#define __INT8_TYPE__ char
 // ARM-BE:#define __INTMAX_MAX__ 9223372036854775807LL
 // ARM-BE:#define __INTMAX_TYPE__ long long int
 // ARM-BE:#define __INTMAX_WIDTH__ 64
+// ARM-BE:#define __INTPTR_MAX__ 2147483647L
 // ARM-BE:#define __INTPTR_TYPE__ long int
 // ARM-BE:#define __INTPTR_WIDTH__ 32
+// ARM-BE:#define __INT_FAST16_MAX__ 32767
+// ARM-BE:#define __INT_FAST16_TYPE__ short
+// ARM-BE:#define __INT_FAST32_MAX__ 2147483647
+// ARM-BE:#define __INT_FAST32_TYPE__ int
+// ARM-BE:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARM-BE:#define __INT_FAST64_TYPE__ long long int
+// ARM-BE:#define __INT_FAST8_MAX__ 127
+// ARM-BE:#define __INT_FAST8_TYPE__ char
+// ARM-BE:#define __INT_LEAST16_MAX__ 32767
+// ARM-BE:#define __INT_LEAST16_TYPE__ short
+// ARM-BE:#define __INT_LEAST32_MAX__ 2147483647
+// ARM-BE:#define __INT_LEAST32_TYPE__ int
+// ARM-BE:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARM-BE:#define __INT_LEAST64_TYPE__ long long int
+// ARM-BE:#define __INT_LEAST8_MAX__ 127
+// ARM-BE:#define __INT_LEAST8_TYPE__ char
 // ARM-BE:#define __INT_MAX__ 2147483647
 // ARM-BE:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // ARM-BE:#define __LDBL_DIG__ 15
@@ -715,7 +970,40 @@
 // ARM-BE:#define __SIZE_TYPE__ unsigned int
 // ARM-BE:#define __SIZE_WIDTH__ 32
 // ARM-BE:#define __THUMB_INTERWORK__ 1
+// ARM-BE:#define __UINT16_C_SUFFIX__ U
+// ARM-BE:#define __UINT16_MAX__ 65535U
+// ARM-BE:#define __UINT16_TYPE__ unsigned short
+// ARM-BE:#define __UINT32_C_SUFFIX__ U
+// ARM-BE:#define __UINT32_MAX__ 4294967295U
+// ARM-BE:#define __UINT32_TYPE__ unsigned int
+// ARM-BE:#define __UINT64_C_SUFFIX__ ULL
+// ARM-BE:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARM-BE:#define __UINT64_TYPE__ long long unsigned int
+// ARM-BE:#define __UINT8_C_SUFFIX__ U
+// ARM-BE:#define __UINT8_MAX__ 255U
+// ARM-BE:#define __UINT8_TYPE__ unsigned char
+// ARM-BE:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // ARM-BE:#define __UINTMAX_TYPE__ long long unsigned int
+// ARM-BE:#define __UINTMAX_WIDTH__ 64
+// ARM-BE:#define __UINTPTR_MAX__ 4294967295U
+// ARM-BE:#define __UINTPTR_TYPE__ unsigned int
+// ARM-BE:#define __UINTPTR_WIDTH__ 32
+// ARM-BE:#define __UINT_FAST16_MAX__ 65535U
+// ARM-BE:#define __UINT_FAST16_TYPE__ unsigned short
+// ARM-BE:#define __UINT_FAST32_MAX__ 4294967295U
+// ARM-BE:#define __UINT_FAST32_TYPE__ unsigned int
+// ARM-BE:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARM-BE:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARM-BE:#define __UINT_FAST8_MAX__ 255U
+// ARM-BE:#define __UINT_FAST8_TYPE__ unsigned char
+// ARM-BE:#define __UINT_LEAST16_MAX__ 65535U
+// ARM-BE:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARM-BE:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARM-BE:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARM-BE:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARM-BE:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARM-BE:#define __UINT_LEAST8_MAX__ 255U
+// ARM-BE:#define __UINT_LEAST8_TYPE__ unsigned char
 // ARM-BE:#define __USER_LABEL_PREFIX__ _
 // ARM-BE:#define __WCHAR_MAX__ 4294967295U
 // ARM-BE:#define __WCHAR_TYPE__ unsigned int
@@ -770,16 +1058,37 @@
 // ARMEABISOFTFP:#define __FLT_MIN_EXP__ (-125)
 // ARMEABISOFTFP:#define __FLT_MIN__ 1.17549435e-38F
 // ARMEABISOFTFP:#define __FLT_RADIX__ 2
+// ARMEABISOFTFP:#define __INT16_MAX__ 32767
 // ARMEABISOFTFP:#define __INT16_TYPE__ short
+// ARMEABISOFTFP:#define __INT32_MAX__ 2147483647
 // ARMEABISOFTFP:#define __INT32_TYPE__ int
 // ARMEABISOFTFP:#define __INT64_C_SUFFIX__ LL
+// ARMEABISOFTFP:#define __INT64_MAX__ 9223372036854775807LL
 // ARMEABISOFTFP:#define __INT64_TYPE__ long long int
+// ARMEABISOFTFP:#define __INT8_MAX__ 127
 // ARMEABISOFTFP:#define __INT8_TYPE__ char
 // ARMEABISOFTFP:#define __INTMAX_MAX__ 9223372036854775807LL
 // ARMEABISOFTFP:#define __INTMAX_TYPE__ long long int
 // ARMEABISOFTFP:#define __INTMAX_WIDTH__ 64
+// ARMEABISOFTFP:#define __INTPTR_MAX__ 2147483647L
 // ARMEABISOFTFP:#define __INTPTR_TYPE__ long int
 // ARMEABISOFTFP:#define __INTPTR_WIDTH__ 32
+// ARMEABISOFTFP:#define __INT_FAST16_MAX__ 32767
+// ARMEABISOFTFP:#define __INT_FAST16_TYPE__ short
+// ARMEABISOFTFP:#define __INT_FAST32_MAX__ 2147483647
+// ARMEABISOFTFP:#define __INT_FAST32_TYPE__ int
+// ARMEABISOFTFP:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARMEABISOFTFP:#define __INT_FAST64_TYPE__ long long int
+// ARMEABISOFTFP:#define __INT_FAST8_MAX__ 127
+// ARMEABISOFTFP:#define __INT_FAST8_TYPE__ char
+// ARMEABISOFTFP:#define __INT_LEAST16_MAX__ 32767
+// ARMEABISOFTFP:#define __INT_LEAST16_TYPE__ short
+// ARMEABISOFTFP:#define __INT_LEAST32_MAX__ 2147483647
+// ARMEABISOFTFP:#define __INT_LEAST32_TYPE__ int
+// ARMEABISOFTFP:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARMEABISOFTFP:#define __INT_LEAST64_TYPE__ long long int
+// ARMEABISOFTFP:#define __INT_LEAST8_MAX__ 127
+// ARMEABISOFTFP:#define __INT_LEAST8_TYPE__ char
 // ARMEABISOFTFP:#define __INT_MAX__ 2147483647
 // ARMEABISOFTFP:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // ARMEABISOFTFP:#define __LDBL_DIG__ 15
@@ -822,7 +1131,40 @@
 // ARMEABISOFTFP:#define __SIZE_WIDTH__ 32
 // ARMEABISOFTFP:#define __SOFTFP__ 1
 // ARMEABISOFTFP:#define __THUMB_INTERWORK__ 1
+// ARMEABISOFTFP:#define __UINT16_C_SUFFIX__ U
+// ARMEABISOFTFP:#define __UINT16_MAX__ 65535U
+// ARMEABISOFTFP:#define __UINT16_TYPE__ unsigned short
+// ARMEABISOFTFP:#define __UINT32_C_SUFFIX__ U
+// ARMEABISOFTFP:#define __UINT32_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINT32_TYPE__ unsigned int
+// ARMEABISOFTFP:#define __UINT64_C_SUFFIX__ ULL
+// ARMEABISOFTFP:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARMEABISOFTFP:#define __UINT64_TYPE__ long long unsigned int
+// ARMEABISOFTFP:#define __UINT8_C_SUFFIX__ U
+// ARMEABISOFTFP:#define __UINT8_MAX__ 255U
+// ARMEABISOFTFP:#define __UINT8_TYPE__ unsigned char
+// ARMEABISOFTFP:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // ARMEABISOFTFP:#define __UINTMAX_TYPE__ long long unsigned int
+// ARMEABISOFTFP:#define __UINTMAX_WIDTH__ 64
+// ARMEABISOFTFP:#define __UINTPTR_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINTPTR_TYPE__ unsigned int
+// ARMEABISOFTFP:#define __UINTPTR_WIDTH__ 32
+// ARMEABISOFTFP:#define __UINT_FAST16_MAX__ 65535U
+// ARMEABISOFTFP:#define __UINT_FAST16_TYPE__ unsigned short
+// ARMEABISOFTFP:#define __UINT_FAST32_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINT_FAST32_TYPE__ unsigned int
+// ARMEABISOFTFP:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARMEABISOFTFP:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARMEABISOFTFP:#define __UINT_FAST8_MAX__ 255U
+// ARMEABISOFTFP:#define __UINT_FAST8_TYPE__ unsigned char
+// ARMEABISOFTFP:#define __UINT_LEAST16_MAX__ 65535U
+// ARMEABISOFTFP:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARMEABISOFTFP:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARMEABISOFTFP:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARMEABISOFTFP:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARMEABISOFTFP:#define __UINT_LEAST8_MAX__ 255U
+// ARMEABISOFTFP:#define __UINT_LEAST8_TYPE__ unsigned char
 // ARMEABISOFTFP:#define __USER_LABEL_PREFIX__
 // ARMEABISOFTFP:#define __WCHAR_MAX__ 4294967295U
 // ARMEABISOFTFP:#define __WCHAR_TYPE__ unsigned int
@@ -877,16 +1219,37 @@
 // ARMEABIHARDFP:#define __FLT_MIN_EXP__ (-125)
 // ARMEABIHARDFP:#define __FLT_MIN__ 1.17549435e-38F
 // ARMEABIHARDFP:#define __FLT_RADIX__ 2
+// ARMEABIHARDFP:#define __INT16_MAX__ 32767
 // ARMEABIHARDFP:#define __INT16_TYPE__ short
+// ARMEABIHARDFP:#define __INT32_MAX__ 2147483647
 // ARMEABIHARDFP:#define __INT32_TYPE__ int
 // ARMEABIHARDFP:#define __INT64_C_SUFFIX__ LL
+// ARMEABIHARDFP:#define __INT64_MAX__ 9223372036854775807LL
 // ARMEABIHARDFP:#define __INT64_TYPE__ long long int
+// ARMEABIHARDFP:#define __INT8_MAX__ 127
 // ARMEABIHARDFP:#define __INT8_TYPE__ char
 // ARMEABIHARDFP:#define __INTMAX_MAX__ 9223372036854775807LL
 // ARMEABIHARDFP:#define __INTMAX_TYPE__ long long int
 // ARMEABIHARDFP:#define __INTMAX_WIDTH__ 64
+// ARMEABIHARDFP:#define __INTPTR_MAX__ 2147483647L
 // ARMEABIHARDFP:#define __INTPTR_TYPE__ long int
 // ARMEABIHARDFP:#define __INTPTR_WIDTH__ 32
+// ARMEABIHARDFP:#define __INT_FAST16_MAX__ 32767
+// ARMEABIHARDFP:#define __INT_FAST16_TYPE__ short
+// ARMEABIHARDFP:#define __INT_FAST32_MAX__ 2147483647
+// ARMEABIHARDFP:#define __INT_FAST32_TYPE__ int
+// ARMEABIHARDFP:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARMEABIHARDFP:#define __INT_FAST64_TYPE__ long long int
+// ARMEABIHARDFP:#define __INT_FAST8_MAX__ 127
+// ARMEABIHARDFP:#define __INT_FAST8_TYPE__ char
+// ARMEABIHARDFP:#define __INT_LEAST16_MAX__ 32767
+// ARMEABIHARDFP:#define __INT_LEAST16_TYPE__ short
+// ARMEABIHARDFP:#define __INT_LEAST32_MAX__ 2147483647
+// ARMEABIHARDFP:#define __INT_LEAST32_TYPE__ int
+// ARMEABIHARDFP:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARMEABIHARDFP:#define __INT_LEAST64_TYPE__ long long int
+// ARMEABIHARDFP:#define __INT_LEAST8_MAX__ 127
+// ARMEABIHARDFP:#define __INT_LEAST8_TYPE__ char
 // ARMEABIHARDFP:#define __INT_MAX__ 2147483647
 // ARMEABIHARDFP:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // ARMEABIHARDFP:#define __LDBL_DIG__ 15
@@ -929,7 +1292,40 @@
 // ARMEABIHARDFP:#define __SIZE_WIDTH__ 32
 // ARMEABIHARDFP-NOT:#define __SOFTFP__ 1
 // ARMEABIHARDFP:#define __THUMB_INTERWORK__ 1
+// ARMEABIHARDFP:#define __UINT16_C_SUFFIX__ U
+// ARMEABIHARDFP:#define __UINT16_MAX__ 65535U
+// ARMEABIHARDFP:#define __UINT16_TYPE__ unsigned short
+// ARMEABIHARDFP:#define __UINT32_C_SUFFIX__ U
+// ARMEABIHARDFP:#define __UINT32_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINT32_TYPE__ unsigned int
+// ARMEABIHARDFP:#define __UINT64_C_SUFFIX__ ULL
+// ARMEABIHARDFP:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARMEABIHARDFP:#define __UINT64_TYPE__ long long unsigned int
+// ARMEABIHARDFP:#define __UINT8_C_SUFFIX__ U
+// ARMEABIHARDFP:#define __UINT8_MAX__ 255U
+// ARMEABIHARDFP:#define __UINT8_TYPE__ unsigned char
+// ARMEABIHARDFP:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // ARMEABIHARDFP:#define __UINTMAX_TYPE__ long long unsigned int
+// ARMEABIHARDFP:#define __UINTMAX_WIDTH__ 64
+// ARMEABIHARDFP:#define __UINTPTR_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINTPTR_TYPE__ unsigned int
+// ARMEABIHARDFP:#define __UINTPTR_WIDTH__ 32
+// ARMEABIHARDFP:#define __UINT_FAST16_MAX__ 65535U
+// ARMEABIHARDFP:#define __UINT_FAST16_TYPE__ unsigned short
+// ARMEABIHARDFP:#define __UINT_FAST32_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINT_FAST32_TYPE__ unsigned int
+// ARMEABIHARDFP:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARMEABIHARDFP:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARMEABIHARDFP:#define __UINT_FAST8_MAX__ 255U
+// ARMEABIHARDFP:#define __UINT_FAST8_TYPE__ unsigned char
+// ARMEABIHARDFP:#define __UINT_LEAST16_MAX__ 65535U
+// ARMEABIHARDFP:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARMEABIHARDFP:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARMEABIHARDFP:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARMEABIHARDFP:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARMEABIHARDFP:#define __UINT_LEAST8_MAX__ 255U
+// ARMEABIHARDFP:#define __UINT_LEAST8_TYPE__ unsigned char
 // ARMEABIHARDFP:#define __USER_LABEL_PREFIX__
 // ARMEABIHARDFP:#define __WCHAR_MAX__ 4294967295U
 // ARMEABIHARDFP:#define __WCHAR_TYPE__ unsigned int
@@ -982,16 +1378,37 @@
 // ARM-NETBSD:#define __FLT_MIN_EXP__ (-125)
 // ARM-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
 // ARM-NETBSD:#define __FLT_RADIX__ 2
+// ARM-NETBSD:#define __INT16_MAX__ 32767
 // ARM-NETBSD:#define __INT16_TYPE__ short
+// ARM-NETBSD:#define __INT32_MAX__ 2147483647
 // ARM-NETBSD:#define __INT32_TYPE__ int
 // ARM-NETBSD:#define __INT64_C_SUFFIX__ LL
+// ARM-NETBSD:#define __INT64_MAX__ 9223372036854775807LL
 // ARM-NETBSD:#define __INT64_TYPE__ long long int
+// ARM-NETBSD:#define __INT8_MAX__ 127
 // ARM-NETBSD:#define __INT8_TYPE__ char
 // ARM-NETBSD:#define __INTMAX_MAX__ 9223372036854775807LL
 // ARM-NETBSD:#define __INTMAX_TYPE__ long long int
 // ARM-NETBSD:#define __INTMAX_WIDTH__ 64
+// ARM-NETBSD:#define __INTPTR_MAX__ 2147483647L
 // ARM-NETBSD:#define __INTPTR_TYPE__ long int
 // ARM-NETBSD:#define __INTPTR_WIDTH__ 32
+// ARM-NETBSD:#define __INT_FAST16_MAX__ 32767
+// ARM-NETBSD:#define __INT_FAST16_TYPE__ short
+// ARM-NETBSD:#define __INT_FAST32_MAX__ 2147483647
+// ARM-NETBSD:#define __INT_FAST32_TYPE__ int
+// ARM-NETBSD:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARM-NETBSD:#define __INT_FAST64_TYPE__ long long int
+// ARM-NETBSD:#define __INT_FAST8_MAX__ 127
+// ARM-NETBSD:#define __INT_FAST8_TYPE__ char
+// ARM-NETBSD:#define __INT_LEAST16_MAX__ 32767
+// ARM-NETBSD:#define __INT_LEAST16_TYPE__ short
+// ARM-NETBSD:#define __INT_LEAST32_MAX__ 2147483647
+// ARM-NETBSD:#define __INT_LEAST32_TYPE__ int
+// ARM-NETBSD:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARM-NETBSD:#define __INT_LEAST64_TYPE__ long long int
+// ARM-NETBSD:#define __INT_LEAST8_MAX__ 127
+// ARM-NETBSD:#define __INT_LEAST8_TYPE__ char
 // ARM-NETBSD:#define __INT_MAX__ 2147483647
 // ARM-NETBSD:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // ARM-NETBSD:#define __LDBL_DIG__ 15
@@ -1033,7 +1450,40 @@
 // ARM-NETBSD:#define __SIZE_TYPE__ long unsigned int
 // ARM-NETBSD:#define __SIZE_WIDTH__ 32
 // ARM-NETBSD:#define __THUMB_INTERWORK__ 1
+// ARM-NETBSD:#define __UINT16_C_SUFFIX__ U
+// ARM-NETBSD:#define __UINT16_MAX__ 65535U
+// ARM-NETBSD:#define __UINT16_TYPE__ unsigned short
+// ARM-NETBSD:#define __UINT32_C_SUFFIX__ U
+// ARM-NETBSD:#define __UINT32_MAX__ 4294967295U
+// ARM-NETBSD:#define __UINT32_TYPE__ unsigned int
+// ARM-NETBSD:#define __UINT64_C_SUFFIX__ ULL
+// ARM-NETBSD:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARM-NETBSD:#define __UINT64_TYPE__ long long unsigned int
+// ARM-NETBSD:#define __UINT8_C_SUFFIX__ U
+// ARM-NETBSD:#define __UINT8_MAX__ 255U
+// ARM-NETBSD:#define __UINT8_TYPE__ unsigned char
+// ARM-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // ARM-NETBSD:#define __UINTMAX_TYPE__ long long unsigned int
+// ARM-NETBSD:#define __UINTMAX_WIDTH__ 64
+// ARM-NETBSD:#define __UINTPTR_MAX__ 4294967295U
+// ARM-NETBSD:#define __UINTPTR_TYPE__ unsigned int
+// ARM-NETBSD:#define __UINTPTR_WIDTH__ 32
+// ARM-NETBSD:#define __UINT_FAST16_MAX__ 65535U
+// ARM-NETBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// ARM-NETBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// ARM-NETBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// ARM-NETBSD:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARM-NETBSD:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARM-NETBSD:#define __UINT_FAST8_MAX__ 255U
+// ARM-NETBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// ARM-NETBSD:#define __UINT_LEAST16_MAX__ 65535U
+// ARM-NETBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARM-NETBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARM-NETBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARM-NETBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARM-NETBSD:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARM-NETBSD:#define __UINT_LEAST8_MAX__ 255U
+// ARM-NETBSD:#define __UINT_LEAST8_TYPE__ unsigned char
 // ARM-NETBSD:#define __USER_LABEL_PREFIX__
 // ARM-NETBSD:#define __WCHAR_MAX__ 2147483647
 // ARM-NETBSD:#define __WCHAR_TYPE__ int
@@ -1139,16 +1589,37 @@
 // I386:#define __FLT_MIN_EXP__ (-125)
 // I386:#define __FLT_MIN__ 1.17549435e-38F
 // I386:#define __FLT_RADIX__ 2
+// I386:#define __INT16_MAX__ 32767
 // I386:#define __INT16_TYPE__ short
+// I386:#define __INT32_MAX__ 2147483647
 // I386:#define __INT32_TYPE__ int
 // I386:#define __INT64_C_SUFFIX__ LL
+// I386:#define __INT64_MAX__ 9223372036854775807LL
 // I386:#define __INT64_TYPE__ long long int
+// I386:#define __INT8_MAX__ 127
 // I386:#define __INT8_TYPE__ char
 // I386:#define __INTMAX_MAX__ 9223372036854775807LL
 // I386:#define __INTMAX_TYPE__ long long int
 // I386:#define __INTMAX_WIDTH__ 64
+// I386:#define __INTPTR_MAX__ 2147483647
 // I386:#define __INTPTR_TYPE__ int
 // I386:#define __INTPTR_WIDTH__ 32
+// I386:#define __INT_FAST16_MAX__ 32767
+// I386:#define __INT_FAST16_TYPE__ short
+// I386:#define __INT_FAST32_MAX__ 2147483647
+// I386:#define __INT_FAST32_TYPE__ int
+// I386:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// I386:#define __INT_FAST64_TYPE__ long long int
+// I386:#define __INT_FAST8_MAX__ 127
+// I386:#define __INT_FAST8_TYPE__ char
+// I386:#define __INT_LEAST16_MAX__ 32767
+// I386:#define __INT_LEAST16_TYPE__ short
+// I386:#define __INT_LEAST32_MAX__ 2147483647
+// I386:#define __INT_LEAST32_TYPE__ int
+// I386:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// I386:#define __INT_LEAST64_TYPE__ long long int
+// I386:#define __INT_LEAST8_MAX__ 127
+// I386:#define __INT_LEAST8_TYPE__ char
 // I386:#define __INT_MAX__ 2147483647
 // I386:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // I386:#define __LDBL_DIG__ 18
@@ -1190,7 +1661,40 @@
 // I386:#define __SIZE_MAX__ 4294967295U
 // I386:#define __SIZE_TYPE__ unsigned int
 // I386:#define __SIZE_WIDTH__ 32
+// I386:#define __UINT16_C_SUFFIX__ U
+// I386:#define __UINT16_MAX__ 65535U
+// I386:#define __UINT16_TYPE__ unsigned short
+// I386:#define __UINT32_C_SUFFIX__ U
+// I386:#define __UINT32_MAX__ 4294967295U
+// I386:#define __UINT32_TYPE__ unsigned int
+// I386:#define __UINT64_C_SUFFIX__ ULL
+// I386:#define __UINT64_MAX__ 18446744073709551615ULL
+// I386:#define __UINT64_TYPE__ long long unsigned int
+// I386:#define __UINT8_C_SUFFIX__ U
+// I386:#define __UINT8_MAX__ 255U
+// I386:#define __UINT8_TYPE__ unsigned char
+// I386:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // I386:#define __UINTMAX_TYPE__ long long unsigned int
+// I386:#define __UINTMAX_WIDTH__ 64
+// I386:#define __UINTPTR_MAX__ 4294967295U
+// I386:#define __UINTPTR_TYPE__ unsigned int
+// I386:#define __UINTPTR_WIDTH__ 32
+// I386:#define __UINT_FAST16_MAX__ 65535U
+// I386:#define __UINT_FAST16_TYPE__ unsigned short
+// I386:#define __UINT_FAST32_MAX__ 4294967295U
+// I386:#define __UINT_FAST32_TYPE__ unsigned int
+// I386:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// I386:#define __UINT_FAST64_TYPE__ long long unsigned int
+// I386:#define __UINT_FAST8_MAX__ 255U
+// I386:#define __UINT_FAST8_TYPE__ unsigned char
+// I386:#define __UINT_LEAST16_MAX__ 65535U
+// I386:#define __UINT_LEAST16_TYPE__ unsigned short
+// I386:#define __UINT_LEAST32_MAX__ 4294967295U
+// I386:#define __UINT_LEAST32_TYPE__ unsigned int
+// I386:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// I386:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// I386:#define __UINT_LEAST8_MAX__ 255U
+// I386:#define __UINT_LEAST8_TYPE__ unsigned char
 // I386:#define __USER_LABEL_PREFIX__ _
 // I386:#define __WCHAR_MAX__ 2147483647
 // I386:#define __WCHAR_TYPE__ int
@@ -1237,16 +1741,37 @@
 // I386-LINUX:#define __FLT_MIN_EXP__ (-125)
 // I386-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // I386-LINUX:#define __FLT_RADIX__ 2
+// I386-LINUX:#define __INT16_MAX__ 32767
 // I386-LINUX:#define __INT16_TYPE__ short
+// I386-LINUX:#define __INT32_MAX__ 2147483647
 // I386-LINUX:#define __INT32_TYPE__ int
 // I386-LINUX:#define __INT64_C_SUFFIX__ LL
+// I386-LINUX:#define __INT64_MAX__ 9223372036854775807LL
 // I386-LINUX:#define __INT64_TYPE__ long long int
+// I386-LINUX:#define __INT8_MAX__ 127
 // I386-LINUX:#define __INT8_TYPE__ char
 // I386-LINUX:#define __INTMAX_MAX__ 9223372036854775807LL
 // I386-LINUX:#define __INTMAX_TYPE__ long long int
 // I386-LINUX:#define __INTMAX_WIDTH__ 64
+// I386-LINUX:#define __INTPTR_MAX__ 2147483647
 // I386-LINUX:#define __INTPTR_TYPE__ int
 // I386-LINUX:#define __INTPTR_WIDTH__ 32
+// I386-LINUX:#define __INT_FAST16_MAX__ 32767
+// I386-LINUX:#define __INT_FAST16_TYPE__ short
+// I386-LINUX:#define __INT_FAST32_MAX__ 2147483647
+// I386-LINUX:#define __INT_FAST32_TYPE__ int
+// I386-LINUX:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// I386-LINUX:#define __INT_FAST64_TYPE__ long long int
+// I386-LINUX:#define __INT_FAST8_MAX__ 127
+// I386-LINUX:#define __INT_FAST8_TYPE__ char
+// I386-LINUX:#define __INT_LEAST16_MAX__ 32767
+// I386-LINUX:#define __INT_LEAST16_TYPE__ short
+// I386-LINUX:#define __INT_LEAST32_MAX__ 2147483647
+// I386-LINUX:#define __INT_LEAST32_TYPE__ int
+// I386-LINUX:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// I386-LINUX:#define __INT_LEAST64_TYPE__ long long int
+// I386-LINUX:#define __INT_LEAST8_MAX__ 127
+// I386-LINUX:#define __INT_LEAST8_TYPE__ char
 // I386-LINUX:#define __INT_MAX__ 2147483647
 // I386-LINUX:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // I386-LINUX:#define __LDBL_DIG__ 18
@@ -1288,7 +1813,40 @@
 // I386-LINUX:#define __SIZE_MAX__ 4294967295U
 // I386-LINUX:#define __SIZE_TYPE__ unsigned int
 // I386-LINUX:#define __SIZE_WIDTH__ 32
+// I386-LINUX:#define __UINT16_C_SUFFIX__ U
+// I386-LINUX:#define __UINT16_MAX__ 65535U
+// I386-LINUX:#define __UINT16_TYPE__ unsigned short
+// I386-LINUX:#define __UINT32_C_SUFFIX__ U
+// I386-LINUX:#define __UINT32_MAX__ 4294967295U
+// I386-LINUX:#define __UINT32_TYPE__ unsigned int
+// I386-LINUX:#define __UINT64_C_SUFFIX__ ULL
+// I386-LINUX:#define __UINT64_MAX__ 18446744073709551615ULL
+// I386-LINUX:#define __UINT64_TYPE__ long long unsigned int
+// I386-LINUX:#define __UINT8_C_SUFFIX__ U
+// I386-LINUX:#define __UINT8_MAX__ 255U
+// I386-LINUX:#define __UINT8_TYPE__ unsigned char
+// I386-LINUX:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // I386-LINUX:#define __UINTMAX_TYPE__ long long unsigned int
+// I386-LINUX:#define __UINTMAX_WIDTH__ 64
+// I386-LINUX:#define __UINTPTR_MAX__ 4294967295U
+// I386-LINUX:#define __UINTPTR_TYPE__ unsigned int
+// I386-LINUX:#define __UINTPTR_WIDTH__ 32
+// I386-LINUX:#define __UINT_FAST16_MAX__ 65535U
+// I386-LINUX:#define __UINT_FAST16_TYPE__ unsigned short
+// I386-LINUX:#define __UINT_FAST32_MAX__ 4294967295U
+// I386-LINUX:#define __UINT_FAST32_TYPE__ unsigned int
+// I386-LINUX:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// I386-LINUX:#define __UINT_FAST64_TYPE__ long long unsigned int
+// I386-LINUX:#define __UINT_FAST8_MAX__ 255U
+// I386-LINUX:#define __UINT_FAST8_TYPE__ unsigned char
+// I386-LINUX:#define __UINT_LEAST16_MAX__ 65535U
+// I386-LINUX:#define __UINT_LEAST16_TYPE__ unsigned short
+// I386-LINUX:#define __UINT_LEAST32_MAX__ 4294967295U
+// I386-LINUX:#define __UINT_LEAST32_TYPE__ unsigned int
+// I386-LINUX:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// I386-LINUX:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// I386-LINUX:#define __UINT_LEAST8_MAX__ 255U
+// I386-LINUX:#define __UINT_LEAST8_TYPE__ unsigned char
 // I386-LINUX:#define __USER_LABEL_PREFIX__
 // I386-LINUX:#define __WCHAR_MAX__ 2147483647
 // I386-LINUX:#define __WCHAR_TYPE__ int
@@ -1335,16 +1893,37 @@
 // I386-NETBSD:#define __FLT_MIN_EXP__ (-125)
 // I386-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
 // I386-NETBSD:#define __FLT_RADIX__ 2
+// I386-NETBSD:#define __INT16_MAX__ 32767
 // I386-NETBSD:#define __INT16_TYPE__ short
+// I386-NETBSD:#define __INT32_MAX__ 2147483647
 // I386-NETBSD:#define __INT32_TYPE__ int
 // I386-NETBSD:#define __INT64_C_SUFFIX__ LL
+// I386-NETBSD:#define __INT64_MAX__ 9223372036854775807LL
 // I386-NETBSD:#define __INT64_TYPE__ long long int
+// I386-NETBSD:#define __INT8_MAX__ 127
 // I386-NETBSD:#define __INT8_TYPE__ char
 // I386-NETBSD:#define __INTMAX_MAX__ 9223372036854775807LL
 // I386-NETBSD:#define __INTMAX_TYPE__ long long int
 // I386-NETBSD:#define __INTMAX_WIDTH__ 64
+// I386-NETBSD:#define __INTPTR_MAX__ 2147483647
 // I386-NETBSD:#define __INTPTR_TYPE__ int
 // I386-NETBSD:#define __INTPTR_WIDTH__ 32
+// I386-NETBSD:#define __INT_FAST16_MAX__ 32767
+// I386-NETBSD:#define __INT_FAST16_TYPE__ short
+// I386-NETBSD:#define __INT_FAST32_MAX__ 2147483647
+// I386-NETBSD:#define __INT_FAST32_TYPE__ int
+// I386-NETBSD:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// I386-NETBSD:#define __INT_FAST64_TYPE__ long long int
+// I386-NETBSD:#define __INT_FAST8_MAX__ 127
+// I386-NETBSD:#define __INT_FAST8_TYPE__ char
+// I386-NETBSD:#define __INT_LEAST16_MAX__ 32767
+// I386-NETBSD:#define __INT_LEAST16_TYPE__ short
+// I386-NETBSD:#define __INT_LEAST32_MAX__ 2147483647
+// I386-NETBSD:#define __INT_LEAST32_TYPE__ int
+// I386-NETBSD:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// I386-NETBSD:#define __INT_LEAST64_TYPE__ long long int
+// I386-NETBSD:#define __INT_LEAST8_MAX__ 127
+// I386-NETBSD:#define __INT_LEAST8_TYPE__ char
 // I386-NETBSD:#define __INT_MAX__ 2147483647
 // I386-NETBSD:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // I386-NETBSD:#define __LDBL_DIG__ 18
@@ -1386,7 +1965,40 @@
 // I386-NETBSD:#define __SIZE_MAX__ 4294967295U
 // I386-NETBSD:#define __SIZE_TYPE__ unsigned int
 // I386-NETBSD:#define __SIZE_WIDTH__ 32
+// I386-NETBSD:#define __UINT16_C_SUFFIX__ U
+// I386-NETBSD:#define __UINT16_MAX__ 65535U
+// I386-NETBSD:#define __UINT16_TYPE__ unsigned short
+// I386-NETBSD:#define __UINT32_C_SUFFIX__ U
+// I386-NETBSD:#define __UINT32_MAX__ 4294967295U
+// I386-NETBSD:#define __UINT32_TYPE__ unsigned int
+// I386-NETBSD:#define __UINT64_C_SUFFIX__ ULL
+// I386-NETBSD:#define __UINT64_MAX__ 18446744073709551615ULL
+// I386-NETBSD:#define __UINT64_TYPE__ long long unsigned int
+// I386-NETBSD:#define __UINT8_C_SUFFIX__ U
+// I386-NETBSD:#define __UINT8_MAX__ 255U
+// I386-NETBSD:#define __UINT8_TYPE__ unsigned char
+// I386-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // I386-NETBSD:#define __UINTMAX_TYPE__ long long unsigned int
+// I386-NETBSD:#define __UINTMAX_WIDTH__ 64
+// I386-NETBSD:#define __UINTPTR_MAX__ 4294967295U
+// I386-NETBSD:#define __UINTPTR_TYPE__ unsigned int
+// I386-NETBSD:#define __UINTPTR_WIDTH__ 32
+// I386-NETBSD:#define __UINT_FAST16_MAX__ 65535U
+// I386-NETBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// I386-NETBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// I386-NETBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// I386-NETBSD:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// I386-NETBSD:#define __UINT_FAST64_TYPE__ long long unsigned int
+// I386-NETBSD:#define __UINT_FAST8_MAX__ 255U
+// I386-NETBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// I386-NETBSD:#define __UINT_LEAST16_MAX__ 65535U
+// I386-NETBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// I386-NETBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// I386-NETBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// I386-NETBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// I386-NETBSD:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// I386-NETBSD:#define __UINT_LEAST8_MAX__ 255U
+// I386-NETBSD:#define __UINT_LEAST8_TYPE__ unsigned char
 // I386-NETBSD:#define __USER_LABEL_PREFIX__
 // I386-NETBSD:#define __WCHAR_MAX__ 2147483647
 // I386-NETBSD:#define __WCHAR_TYPE__ int
@@ -1453,16 +2065,37 @@
 // MIPS32BE:#define __FLT_MIN_EXP__ (-125)
 // MIPS32BE:#define __FLT_MIN__ 1.17549435e-38F
 // MIPS32BE:#define __FLT_RADIX__ 2
+// MIPS32BE:#define __INT16_MAX__ 32767
 // MIPS32BE:#define __INT16_TYPE__ short
+// MIPS32BE:#define __INT32_MAX__ 2147483647
 // MIPS32BE:#define __INT32_TYPE__ int
 // MIPS32BE:#define __INT64_C_SUFFIX__ LL
+// MIPS32BE:#define __INT64_MAX__ 9223372036854775807LL
 // MIPS32BE:#define __INT64_TYPE__ long long int
+// MIPS32BE:#define __INT8_MAX__ 127
 // MIPS32BE:#define __INT8_TYPE__ char
 // MIPS32BE:#define __INTMAX_MAX__ 9223372036854775807LL
 // MIPS32BE:#define __INTMAX_TYPE__ long long int
 // MIPS32BE:#define __INTMAX_WIDTH__ 64
+// MIPS32BE:#define __INTPTR_MAX__ 2147483647L
 // MIPS32BE:#define __INTPTR_TYPE__ long int
 // MIPS32BE:#define __INTPTR_WIDTH__ 32
+// MIPS32BE:#define __INT_FAST16_MAX__ 32767
+// MIPS32BE:#define __INT_FAST16_TYPE__ short
+// MIPS32BE:#define __INT_FAST32_MAX__ 2147483647
+// MIPS32BE:#define __INT_FAST32_TYPE__ int
+// MIPS32BE:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// MIPS32BE:#define __INT_FAST64_TYPE__ long long int
+// MIPS32BE:#define __INT_FAST8_MAX__ 127
+// MIPS32BE:#define __INT_FAST8_TYPE__ char
+// MIPS32BE:#define __INT_LEAST16_MAX__ 32767
+// MIPS32BE:#define __INT_LEAST16_TYPE__ short
+// MIPS32BE:#define __INT_LEAST32_MAX__ 2147483647
+// MIPS32BE:#define __INT_LEAST32_TYPE__ int
+// MIPS32BE:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// MIPS32BE:#define __INT_LEAST64_TYPE__ long long int
+// MIPS32BE:#define __INT_LEAST8_MAX__ 127
+// MIPS32BE:#define __INT_LEAST8_TYPE__ char
 // MIPS32BE:#define __INT_MAX__ 2147483647
 // MIPS32BE:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // MIPS32BE:#define __LDBL_DIG__ 15
@@ -1508,7 +2141,40 @@
 // MIPS32BE:#define __STDC_HOSTED__ 0
 // MIPS32BE:#define __STDC_VERSION__ 199901L
 // MIPS32BE:#define __STDC__ 1
+// MIPS32BE:#define __UINT16_C_SUFFIX__ U
+// MIPS32BE:#define __UINT16_MAX__ 65535U
+// MIPS32BE:#define __UINT16_TYPE__ unsigned short
+// MIPS32BE:#define __UINT32_C_SUFFIX__ U
+// MIPS32BE:#define __UINT32_MAX__ 4294967295U
+// MIPS32BE:#define __UINT32_TYPE__ unsigned int
+// MIPS32BE:#define __UINT64_C_SUFFIX__ ULL
+// MIPS32BE:#define __UINT64_MAX__ 18446744073709551615ULL
+// MIPS32BE:#define __UINT64_TYPE__ long long unsigned int
+// MIPS32BE:#define __UINT8_C_SUFFIX__ U
+// MIPS32BE:#define __UINT8_MAX__ 255U
+// MIPS32BE:#define __UINT8_TYPE__ unsigned char
+// MIPS32BE:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MIPS32BE:#define __UINTMAX_TYPE__ long long unsigned int
+// MIPS32BE:#define __UINTMAX_WIDTH__ 64
+// MIPS32BE:#define __UINTPTR_MAX__ 4294967295U
+// MIPS32BE:#define __UINTPTR_TYPE__ unsigned int
+// MIPS32BE:#define __UINTPTR_WIDTH__ 32
+// MIPS32BE:#define __UINT_FAST16_MAX__ 65535U
+// MIPS32BE:#define __UINT_FAST16_TYPE__ unsigned short
+// MIPS32BE:#define __UINT_FAST32_MAX__ 4294967295U
+// MIPS32BE:#define __UINT_FAST32_TYPE__ unsigned int
+// MIPS32BE:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// MIPS32BE:#define __UINT_FAST64_TYPE__ long long unsigned int
+// MIPS32BE:#define __UINT_FAST8_MAX__ 255U
+// MIPS32BE:#define __UINT_FAST8_TYPE__ unsigned char
+// MIPS32BE:#define __UINT_LEAST16_MAX__ 65535U
+// MIPS32BE:#define __UINT_LEAST16_TYPE__ unsigned short
+// MIPS32BE:#define __UINT_LEAST32_MAX__ 4294967295U
+// MIPS32BE:#define __UINT_LEAST32_TYPE__ unsigned int
+// MIPS32BE:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// MIPS32BE:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// MIPS32BE:#define __UINT_LEAST8_MAX__ 255U
+// MIPS32BE:#define __UINT_LEAST8_TYPE__ unsigned char
 // MIPS32BE:#define __USER_LABEL_PREFIX__ _
 // MIPS32BE:#define __WCHAR_MAX__ 2147483647
 // MIPS32BE:#define __WCHAR_TYPE__ int
@@ -1572,16 +2238,37 @@
 // MIPS32EL:#define __FLT_MIN_EXP__ (-125)
 // MIPS32EL:#define __FLT_MIN__ 1.17549435e-38F
 // MIPS32EL:#define __FLT_RADIX__ 2
+// MIPS32EL:#define __INT16_MAX__ 32767
 // MIPS32EL:#define __INT16_TYPE__ short
+// MIPS32EL:#define __INT32_MAX__ 2147483647
 // MIPS32EL:#define __INT32_TYPE__ int
 // MIPS32EL:#define __INT64_C_SUFFIX__ LL
+// MIPS32EL:#define __INT64_MAX__ 9223372036854775807LL
 // MIPS32EL:#define __INT64_TYPE__ long long int
+// MIPS32EL:#define __INT8_MAX__ 127
 // MIPS32EL:#define __INT8_TYPE__ char
 // MIPS32EL:#define __INTMAX_MAX__ 9223372036854775807LL
 // MIPS32EL:#define __INTMAX_TYPE__ long long int
 // MIPS32EL:#define __INTMAX_WIDTH__ 64
+// MIPS32EL:#define __INTPTR_MAX__ 2147483647L
 // MIPS32EL:#define __INTPTR_TYPE__ long int
 // MIPS32EL:#define __INTPTR_WIDTH__ 32
+// MIPS32EL:#define __INT_FAST16_MAX__ 32767
+// MIPS32EL:#define __INT_FAST16_TYPE__ short
+// MIPS32EL:#define __INT_FAST32_MAX__ 2147483647
+// MIPS32EL:#define __INT_FAST32_TYPE__ int
+// MIPS32EL:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// MIPS32EL:#define __INT_FAST64_TYPE__ long long int
+// MIPS32EL:#define __INT_FAST8_MAX__ 127
+// MIPS32EL:#define __INT_FAST8_TYPE__ char
+// MIPS32EL:#define __INT_LEAST16_MAX__ 32767
+// MIPS32EL:#define __INT_LEAST16_TYPE__ short
+// MIPS32EL:#define __INT_LEAST32_MAX__ 2147483647
+// MIPS32EL:#define __INT_LEAST32_TYPE__ int
+// MIPS32EL:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// MIPS32EL:#define __INT_LEAST64_TYPE__ long long int
+// MIPS32EL:#define __INT_LEAST8_MAX__ 127
+// MIPS32EL:#define __INT_LEAST8_TYPE__ char
 // MIPS32EL:#define __INT_MAX__ 2147483647
 // MIPS32EL:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // MIPS32EL:#define __LDBL_DIG__ 15
@@ -1625,7 +2312,40 @@
 // MIPS32EL:#define __SIZE_MAX__ 4294967295U
 // MIPS32EL:#define __SIZE_TYPE__ unsigned int
 // MIPS32EL:#define __SIZE_WIDTH__ 32
+// MIPS32EL:#define __UINT16_C_SUFFIX__ U
+// MIPS32EL:#define __UINT16_MAX__ 65535U
+// MIPS32EL:#define __UINT16_TYPE__ unsigned short
+// MIPS32EL:#define __UINT32_C_SUFFIX__ U
+// MIPS32EL:#define __UINT32_MAX__ 4294967295U
+// MIPS32EL:#define __UINT32_TYPE__ unsigned int
+// MIPS32EL:#define __UINT64_C_SUFFIX__ ULL
+// MIPS32EL:#define __UINT64_MAX__ 18446744073709551615ULL
+// MIPS32EL:#define __UINT64_TYPE__ long long unsigned int
+// MIPS32EL:#define __UINT8_C_SUFFIX__ U
+// MIPS32EL:#define __UINT8_MAX__ 255U
+// MIPS32EL:#define __UINT8_TYPE__ unsigned char
+// MIPS32EL:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MIPS32EL:#define __UINTMAX_TYPE__ long long unsigned int
+// MIPS32EL:#define __UINTMAX_WIDTH__ 64
+// MIPS32EL:#define __UINTPTR_MAX__ 4294967295U
+// MIPS32EL:#define __UINTPTR_TYPE__ unsigned int
+// MIPS32EL:#define __UINTPTR_WIDTH__ 32
+// MIPS32EL:#define __UINT_FAST16_MAX__ 65535U
+// MIPS32EL:#define __UINT_FAST16_TYPE__ unsigned short
+// MIPS32EL:#define __UINT_FAST32_MAX__ 4294967295U
+// MIPS32EL:#define __UINT_FAST32_TYPE__ unsigned int
+// MIPS32EL:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// MIPS32EL:#define __UINT_FAST64_TYPE__ long long unsigned int
+// MIPS32EL:#define __UINT_FAST8_MAX__ 255U
+// MIPS32EL:#define __UINT_FAST8_TYPE__ unsigned char
+// MIPS32EL:#define __UINT_LEAST16_MAX__ 65535U
+// MIPS32EL:#define __UINT_LEAST16_TYPE__ unsigned short
+// MIPS32EL:#define __UINT_LEAST32_MAX__ 4294967295U
+// MIPS32EL:#define __UINT_LEAST32_TYPE__ unsigned int
+// MIPS32EL:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// MIPS32EL:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// MIPS32EL:#define __UINT_LEAST8_MAX__ 255U
+// MIPS32EL:#define __UINT_LEAST8_TYPE__ unsigned char
 // MIPS32EL:#define __USER_LABEL_PREFIX__ _
 // MIPS32EL:#define __WCHAR_MAX__ 2147483647
 // MIPS32EL:#define __WCHAR_TYPE__ int
@@ -1690,16 +2410,37 @@
 // MIPS64BE:#define __FLT_MIN_EXP__ (-125)
 // MIPS64BE:#define __FLT_MIN__ 1.17549435e-38F
 // MIPS64BE:#define __FLT_RADIX__ 2
+// MIPS64BE:#define __INT16_MAX__ 32767
 // MIPS64BE:#define __INT16_TYPE__ short
+// MIPS64BE:#define __INT32_MAX__ 2147483647
 // MIPS64BE:#define __INT32_TYPE__ int
 // MIPS64BE:#define __INT64_C_SUFFIX__ LL
+// MIPS64BE:#define __INT64_MAX__ 9223372036854775807L
 // MIPS64BE:#define __INT64_TYPE__ long long int
+// MIPS64BE:#define __INT8_MAX__ 127
 // MIPS64BE:#define __INT8_TYPE__ char
 // MIPS64BE:#define __INTMAX_MAX__ 9223372036854775807LL
 // MIPS64BE:#define __INTMAX_TYPE__ long long int
 // MIPS64BE:#define __INTMAX_WIDTH__ 64
+// MIPS64BE:#define __INTPTR_MAX__ 9223372036854775807L
 // MIPS64BE:#define __INTPTR_TYPE__ long int
 // MIPS64BE:#define __INTPTR_WIDTH__ 64
+// MIPS64BE:#define __INT_FAST16_MAX__ 32767
+// MIPS64BE:#define __INT_FAST16_TYPE__ short
+// MIPS64BE:#define __INT_FAST32_MAX__ 2147483647
+// MIPS64BE:#define __INT_FAST32_TYPE__ int
+// MIPS64BE:#define __INT_FAST64_MAX__ 9223372036854775807L
+// MIPS64BE:#define __INT_FAST64_TYPE__ long int
+// MIPS64BE:#define __INT_FAST8_MAX__ 127
+// MIPS64BE:#define __INT_FAST8_TYPE__ char
+// MIPS64BE:#define __INT_LEAST16_MAX__ 32767
+// MIPS64BE:#define __INT_LEAST16_TYPE__ short
+// MIPS64BE:#define __INT_LEAST32_MAX__ 2147483647
+// MIPS64BE:#define __INT_LEAST32_TYPE__ int
+// MIPS64BE:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// MIPS64BE:#define __INT_LEAST64_TYPE__ long int
+// MIPS64BE:#define __INT_LEAST8_MAX__ 127
+// MIPS64BE:#define __INT_LEAST8_TYPE__ char
 // MIPS64BE:#define __INT_MAX__ 2147483647
 // MIPS64BE:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // MIPS64BE:#define __LDBL_DIG__ 33
@@ -1742,7 +2483,40 @@
 // MIPS64BE:#define __SIZE_MAX__ 18446744073709551615UL
 // MIPS64BE:#define __SIZE_TYPE__ long unsigned int
 // MIPS64BE:#define __SIZE_WIDTH__ 64
+// MIPS64BE:#define __UINT16_C_SUFFIX__ U
+// MIPS64BE:#define __UINT16_MAX__ 65535U
+// MIPS64BE:#define __UINT16_TYPE__ unsigned short
+// MIPS64BE:#define __UINT32_C_SUFFIX__ U
+// MIPS64BE:#define __UINT32_MAX__ 4294967295U
+// MIPS64BE:#define __UINT32_TYPE__ unsigned int
+// MIPS64BE:#define __UINT64_C_SUFFIX__ UL
+// MIPS64BE:#define __UINT64_MAX__ 18446744073709551615UL
+// MIPS64BE:#define __UINT64_TYPE__ long unsigned int
+// MIPS64BE:#define __UINT8_C_SUFFIX__ U
+// MIPS64BE:#define __UINT8_MAX__ 255U
+// MIPS64BE:#define __UINT8_TYPE__ unsigned char
+// MIPS64BE:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MIPS64BE:#define __UINTMAX_TYPE__ long long unsigned int
+// MIPS64BE:#define __UINTMAX_WIDTH__ 64
+// MIPS64BE:#define __UINTPTR_MAX__ 18446744073709551615UL
+// MIPS64BE:#define __UINTPTR_TYPE__ long unsigned int
+// MIPS64BE:#define __UINTPTR_WIDTH__ 64
+// MIPS64BE:#define __UINT_FAST16_MAX__ 65535U
+// MIPS64BE:#define __UINT_FAST16_TYPE__ unsigned short
+// MIPS64BE:#define __UINT_FAST32_MAX__ 4294967295U
+// MIPS64BE:#define __UINT_FAST32_TYPE__ unsigned int
+// MIPS64BE:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// MIPS64BE:#define __UINT_FAST64_TYPE__ long unsigned int
+// MIPS64BE:#define __UINT_FAST8_MAX__ 255U
+// MIPS64BE:#define __UINT_FAST8_TYPE__ unsigned char
+// MIPS64BE:#define __UINT_LEAST16_MAX__ 65535U
+// MIPS64BE:#define __UINT_LEAST16_TYPE__ unsigned short
+// MIPS64BE:#define __UINT_LEAST32_MAX__ 4294967295U
+// MIPS64BE:#define __UINT_LEAST32_TYPE__ unsigned int
+// MIPS64BE:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// MIPS64BE:#define __UINT_LEAST64_TYPE__ long unsigned int
+// MIPS64BE:#define __UINT_LEAST8_MAX__ 255U
+// MIPS64BE:#define __UINT_LEAST8_TYPE__ unsigned char
 // MIPS64BE:#define __USER_LABEL_PREFIX__ _
 // MIPS64BE:#define __WCHAR_MAX__ 2147483647
 // MIPS64BE:#define __WCHAR_TYPE__ int
@@ -1808,16 +2582,37 @@
 // MIPS64EL:#define __FLT_MIN_EXP__ (-125)
 // MIPS64EL:#define __FLT_MIN__ 1.17549435e-38F
 // MIPS64EL:#define __FLT_RADIX__ 2
+// MIPS64EL:#define __INT16_MAX__ 32767
 // MIPS64EL:#define __INT16_TYPE__ short
+// MIPS64EL:#define __INT32_MAX__ 2147483647
 // MIPS64EL:#define __INT32_TYPE__ int
 // MIPS64EL:#define __INT64_C_SUFFIX__ LL
+// MIPS64EL:#define __INT64_MAX__ 9223372036854775807L
 // MIPS64EL:#define __INT64_TYPE__ long long int
+// MIPS64EL:#define __INT8_MAX__ 127
 // MIPS64EL:#define __INT8_TYPE__ char
 // MIPS64EL:#define __INTMAX_MAX__ 9223372036854775807LL
 // MIPS64EL:#define __INTMAX_TYPE__ long long int
 // MIPS64EL:#define __INTMAX_WIDTH__ 64
+// MIPS64EL:#define __INTPTR_MAX__ 9223372036854775807L
 // MIPS64EL:#define __INTPTR_TYPE__ long int
 // MIPS64EL:#define __INTPTR_WIDTH__ 64
+// MIPS64EL:#define __INT_FAST16_MAX__ 32767
+// MIPS64EL:#define __INT_FAST16_TYPE__ short
+// MIPS64EL:#define __INT_FAST32_MAX__ 2147483647
+// MIPS64EL:#define __INT_FAST32_TYPE__ int
+// MIPS64EL:#define __INT_FAST64_MAX__ 9223372036854775807L
+// MIPS64EL:#define __INT_FAST64_TYPE__ long int
+// MIPS64EL:#define __INT_FAST8_MAX__ 127
+// MIPS64EL:#define __INT_FAST8_TYPE__ char
+// MIPS64EL:#define __INT_LEAST16_MAX__ 32767
+// MIPS64EL:#define __INT_LEAST16_TYPE__ short
+// MIPS64EL:#define __INT_LEAST32_MAX__ 2147483647
+// MIPS64EL:#define __INT_LEAST32_TYPE__ int
+// MIPS64EL:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// MIPS64EL:#define __INT_LEAST64_TYPE__ long int
+// MIPS64EL:#define __INT_LEAST8_MAX__ 127
+// MIPS64EL:#define __INT_LEAST8_TYPE__ char
 // MIPS64EL:#define __INT_MAX__ 2147483647
 // MIPS64EL:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // MIPS64EL:#define __LDBL_DIG__ 33
@@ -1861,7 +2656,40 @@
 // MIPS64EL:#define __SIZE_MAX__ 18446744073709551615UL
 // MIPS64EL:#define __SIZE_TYPE__ long unsigned int
 // MIPS64EL:#define __SIZE_WIDTH__ 64
+// MIPS64EL:#define __UINT16_C_SUFFIX__ U
+// MIPS64EL:#define __UINT16_MAX__ 65535U
+// MIPS64EL:#define __UINT16_TYPE__ unsigned short
+// MIPS64EL:#define __UINT32_C_SUFFIX__ U
+// MIPS64EL:#define __UINT32_MAX__ 4294967295U
+// MIPS64EL:#define __UINT32_TYPE__ unsigned int
+// MIPS64EL:#define __UINT64_C_SUFFIX__ UL
+// MIPS64EL:#define __UINT64_MAX__ 18446744073709551615UL
+// MIPS64EL:#define __UINT64_TYPE__ long unsigned int
+// MIPS64EL:#define __UINT8_C_SUFFIX__ U
+// MIPS64EL:#define __UINT8_MAX__ 255U
+// MIPS64EL:#define __UINT8_TYPE__ unsigned char
+// MIPS64EL:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MIPS64EL:#define __UINTMAX_TYPE__ long long unsigned int
+// MIPS64EL:#define __UINTMAX_WIDTH__ 64
+// MIPS64EL:#define __UINTPTR_MAX__ 18446744073709551615UL
+// MIPS64EL:#define __UINTPTR_TYPE__ long unsigned int
+// MIPS64EL:#define __UINTPTR_WIDTH__ 64
+// MIPS64EL:#define __UINT_FAST16_MAX__ 65535U
+// MIPS64EL:#define __UINT_FAST16_TYPE__ unsigned short
+// MIPS64EL:#define __UINT_FAST32_MAX__ 4294967295U
+// MIPS64EL:#define __UINT_FAST32_TYPE__ unsigned int
+// MIPS64EL:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// MIPS64EL:#define __UINT_FAST64_TYPE__ long unsigned int
+// MIPS64EL:#define __UINT_FAST8_MAX__ 255U
+// MIPS64EL:#define __UINT_FAST8_TYPE__ unsigned char
+// MIPS64EL:#define __UINT_LEAST16_MAX__ 65535U
+// MIPS64EL:#define __UINT_LEAST16_TYPE__ unsigned short
+// MIPS64EL:#define __UINT_LEAST32_MAX__ 4294967295U
+// MIPS64EL:#define __UINT_LEAST32_TYPE__ unsigned int
+// MIPS64EL:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// MIPS64EL:#define __UINT_LEAST64_TYPE__ long unsigned int
+// MIPS64EL:#define __UINT_LEAST8_MAX__ 255U
+// MIPS64EL:#define __UINT_LEAST8_TYPE__ unsigned char
 // MIPS64EL:#define __USER_LABEL_PREFIX__ _
 // MIPS64EL:#define __WCHAR_MAX__ 2147483647
 // MIPS64EL:#define __WCHAR_TYPE__ int
@@ -1880,7 +2708,7 @@
 // MIPS64EL:#define _mips 1
 // MIPS64EL:#define mips 1
 //
-// Check MIPS arch macros
+// Check MIPS arch and isa macros
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips-none-none \
 // RUN:            < /dev/null \
@@ -1888,6 +2716,8 @@
 //
 // MIPS-ARCH-DEF32:#define _MIPS_ARCH "mips32r2"
 // MIPS-ARCH-DEF32:#define _MIPS_ARCH_MIPS32R2 1
+// MIPS-ARCH-DEF32:#define _MIPS_ISA _MIPS_ISA_MIPS32
+// MIPS-ARCH-DEF32:#define __mips_isa_rev 2
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips-none-nones \
 // RUN:            -target-cpu mips32 < /dev/null \
@@ -1895,6 +2725,8 @@
 //
 // MIPS-ARCH-32:#define _MIPS_ARCH "mips32"
 // MIPS-ARCH-32:#define _MIPS_ARCH_MIPS32 1
+// MIPS-ARCH-32:#define _MIPS_ISA _MIPS_ISA_MIPS32
+// MIPS-ARCH-32:#define __mips_isa_rev 1
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips-none-none \
 // RUN:            -target-cpu mips32r2 < /dev/null \
@@ -1902,6 +2734,8 @@
 //
 // MIPS-ARCH-32R2:#define _MIPS_ARCH "mips32r2"
 // MIPS-ARCH-32R2:#define _MIPS_ARCH_MIPS32R2 1
+// MIPS-ARCH-32R2:#define _MIPS_ISA _MIPS_ISA_MIPS32
+// MIPS-ARCH-32R2:#define __mips_isa_rev 2
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips64-none-none \
 // RUN:            < /dev/null \
@@ -1909,6 +2743,8 @@
 //
 // MIPS-ARCH-DEF64:#define _MIPS_ARCH "mips64r2"
 // MIPS-ARCH-DEF64:#define _MIPS_ARCH_MIPS64R2 1
+// MIPS-ARCH-DEF64:#define _MIPS_ISA _MIPS_ISA_MIPS64
+// MIPS-ARCH-DEF64:#define __mips_isa_rev 2
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips64-none-none \
 // RUN:            -target-cpu mips64 < /dev/null \
@@ -1916,6 +2752,8 @@
 //
 // MIPS-ARCH-64:#define _MIPS_ARCH "mips64"
 // MIPS-ARCH-64:#define _MIPS_ARCH_MIPS64 1
+// MIPS-ARCH-64:#define _MIPS_ISA _MIPS_ISA_MIPS64
+// MIPS-ARCH-64:#define __mips_isa_rev 1
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips64-none-none \
 // RUN:            -target-cpu mips64r2 < /dev/null \
@@ -1923,6 +2761,8 @@
 //
 // MIPS-ARCH-64R2:#define _MIPS_ARCH "mips64r2"
 // MIPS-ARCH-64R2:#define _MIPS_ARCH_MIPS64R2 1
+// MIPS-ARCH-64R2:#define _MIPS_ISA _MIPS_ISA_MIPS64
+// MIPS-ARCH-64R2:#define __mips_isa_rev 2
 //
 // Check MIPS float ABI macros
 //
@@ -2024,6 +2864,16 @@
 // MIPS64-NOMFP64:#define _MIPS_FPSET 32
 // MIPS64-NOMFP64:#define __mips_fpr 32
 //
+// RUN: %clang_cc1 -target-cpu mips32r6 \
+// RUN:   -E -dM -triple=mips-none-none < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-XXR6 %s
+// RUN: %clang_cc1 -target-cpu mips64r6 \
+// RUN:   -E -dM -triple=mips64-none-none < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-XXR6 %s
+// MIPS-XXR6:#define _MIPS_FPSET 32
+// MIPS-XXR6:#define __mips_fpr 64
+// MIPS-XXR6:#define __mips_nan2008 1
+//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=msp430-none-none < /dev/null | FileCheck -check-prefix MSP430 %s
 //
 // MSP430:#define MSP430 1
@@ -2061,15 +2911,38 @@
 // MSP430:#define __FLT_MIN_EXP__ (-125)
 // MSP430:#define __FLT_MIN__ 1.17549435e-38F
 // MSP430:#define __FLT_RADIX__ 2
+// MSP430:#define __INT16_MAX__ 32767
 // MSP430:#define __INT16_TYPE__ short
 // MSP430:#define __INT32_C_SUFFIX__ L
+// MSP430:#define __INT32_MAX__ 2147483647L
 // MSP430:#define __INT32_TYPE__ long int
+// MSP430:#define __INT64_C_SUFFIX__ LL
+// MSP430:#define __INT64_MAX__ 9223372036854775807LL
+// MSP430:#define __INT64_TYPE__ long long int
+// MSP430:#define __INT8_MAX__ 127
 // MSP430:#define __INT8_TYPE__ char
 // MSP430:#define __INTMAX_MAX__ 9223372036854775807LL
 // MSP430:#define __INTMAX_TYPE__ long long int
 // MSP430:#define __INTMAX_WIDTH__ 64
+// MSP430:#define __INTPTR_MAX__ 32767
 // MSP430:#define __INTPTR_TYPE__ int
 // MSP430:#define __INTPTR_WIDTH__ 16
+// MSP430:#define __INT_FAST16_MAX__ 32767
+// MSP430:#define __INT_FAST16_TYPE__ short
+// MSP430:#define __INT_FAST32_MAX__ 2147483647L
+// MSP430:#define __INT_FAST32_TYPE__ long int
+// MSP430:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// MSP430:#define __INT_FAST64_TYPE__ long long int
+// MSP430:#define __INT_FAST8_MAX__ 127
+// MSP430:#define __INT_FAST8_TYPE__ char
+// MSP430:#define __INT_LEAST16_MAX__ 32767
+// MSP430:#define __INT_LEAST16_TYPE__ short
+// MSP430:#define __INT_LEAST32_MAX__ 2147483647L
+// MSP430:#define __INT_LEAST32_TYPE__ long int
+// MSP430:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// MSP430:#define __INT_LEAST64_TYPE__ long long int
+// MSP430:#define __INT_LEAST8_MAX__ 127
+// MSP430:#define __INT_LEAST8_TYPE__ char
 // MSP430:#define __INT_MAX__ 32767
 // MSP430:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // MSP430:#define __LDBL_DIG__ 15
@@ -2110,7 +2983,40 @@
 // MSP430:#define __SIZE_MAX__ 65535U
 // MSP430:#define __SIZE_TYPE__ unsigned int
 // MSP430:#define __SIZE_WIDTH__ 16
+// MSP430:#define __UINT16_C_SUFFIX__ U
+// MSP430:#define __UINT16_MAX__ 65535U
+// MSP430:#define __UINT16_TYPE__ unsigned short
+// MSP430:#define __UINT32_C_SUFFIX__ UL
+// MSP430:#define __UINT32_MAX__ 4294967295UL
+// MSP430:#define __UINT32_TYPE__ long unsigned int
+// MSP430:#define __UINT64_C_SUFFIX__ ULL
+// MSP430:#define __UINT64_MAX__ 18446744073709551615ULL
+// MSP430:#define __UINT64_TYPE__ long long unsigned int
+// MSP430:#define __UINT8_C_SUFFIX__ U
+// MSP430:#define __UINT8_MAX__ 255U
+// MSP430:#define __UINT8_TYPE__ unsigned char
+// MSP430:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MSP430:#define __UINTMAX_TYPE__ long long unsigned int
+// MSP430:#define __UINTMAX_WIDTH__ 64
+// MSP430:#define __UINTPTR_MAX__ 65535U
+// MSP430:#define __UINTPTR_TYPE__ unsigned short
+// MSP430:#define __UINTPTR_WIDTH__ 16
+// MSP430:#define __UINT_FAST16_MAX__ 65535U
+// MSP430:#define __UINT_FAST16_TYPE__ unsigned short
+// MSP430:#define __UINT_FAST32_MAX__ 4294967295UL
+// MSP430:#define __UINT_FAST32_TYPE__ long unsigned int
+// MSP430:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// MSP430:#define __UINT_FAST64_TYPE__ long long unsigned int
+// MSP430:#define __UINT_FAST8_MAX__ 255U
+// MSP430:#define __UINT_FAST8_TYPE__ unsigned char
+// MSP430:#define __UINT_LEAST16_MAX__ 65535U
+// MSP430:#define __UINT_LEAST16_TYPE__ unsigned short
+// MSP430:#define __UINT_LEAST32_MAX__ 4294967295UL
+// MSP430:#define __UINT_LEAST32_TYPE__ long unsigned int
+// MSP430:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// MSP430:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// MSP430:#define __UINT_LEAST8_MAX__ 255U
+// MSP430:#define __UINT_LEAST8_TYPE__ unsigned char
 // MSP430:#define __USER_LABEL_PREFIX__ _
 // MSP430:#define __WCHAR_MAX__ 32767
 // MSP430:#define __WCHAR_TYPE__ int
@@ -2157,16 +3063,37 @@
 // NVPTX32:#define __FLT_MIN_EXP__ (-125)
 // NVPTX32:#define __FLT_MIN__ 1.17549435e-38F
 // NVPTX32:#define __FLT_RADIX__ 2
+// NVPTX32:#define __INT16_MAX__ 32767
 // NVPTX32:#define __INT16_TYPE__ short
+// NVPTX32:#define __INT32_MAX__ 2147483647
 // NVPTX32:#define __INT32_TYPE__ int
 // NVPTX32:#define __INT64_C_SUFFIX__ LL
+// NVPTX32:#define __INT64_MAX__ 9223372036854775807L
 // NVPTX32:#define __INT64_TYPE__ long long int
+// NVPTX32:#define __INT8_MAX__ 127
 // NVPTX32:#define __INT8_TYPE__ char
 // NVPTX32:#define __INTMAX_MAX__ 9223372036854775807LL
 // NVPTX32:#define __INTMAX_TYPE__ long long int
 // NVPTX32:#define __INTMAX_WIDTH__ 64
+// NVPTX32:#define __INTPTR_MAX__ 4294967295U
 // NVPTX32:#define __INTPTR_TYPE__ unsigned int
 // NVPTX32:#define __INTPTR_WIDTH__ 32
+// NVPTX32:#define __INT_FAST16_MAX__ 32767
+// NVPTX32:#define __INT_FAST16_TYPE__ short
+// NVPTX32:#define __INT_FAST32_MAX__ 2147483647
+// NVPTX32:#define __INT_FAST32_TYPE__ int
+// NVPTX32:#define __INT_FAST64_MAX__ 9223372036854775807L
+// NVPTX32:#define __INT_FAST64_TYPE__ long int
+// NVPTX32:#define __INT_FAST8_MAX__ 127
+// NVPTX32:#define __INT_FAST8_TYPE__ char
+// NVPTX32:#define __INT_LEAST16_MAX__ 32767
+// NVPTX32:#define __INT_LEAST16_TYPE__ short
+// NVPTX32:#define __INT_LEAST32_MAX__ 2147483647
+// NVPTX32:#define __INT_LEAST32_TYPE__ int
+// NVPTX32:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// NVPTX32:#define __INT_LEAST64_TYPE__ long int
+// NVPTX32:#define __INT_LEAST8_MAX__ 127
+// NVPTX32:#define __INT_LEAST8_TYPE__ char
 // NVPTX32:#define __INT_MAX__ 2147483647
 // NVPTX32:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // NVPTX32:#define __LDBL_DIG__ 15
@@ -2209,7 +3136,40 @@
 // NVPTX32:#define __SIZE_MAX__ 4294967295U
 // NVPTX32:#define __SIZE_TYPE__ unsigned int
 // NVPTX32:#define __SIZE_WIDTH__ 32
+// NVPTX32:#define __UINT16_C_SUFFIX__ U
+// NVPTX32:#define __UINT16_MAX__ 65535U
+// NVPTX32:#define __UINT16_TYPE__ unsigned short
+// NVPTX32:#define __UINT32_C_SUFFIX__ U
+// NVPTX32:#define __UINT32_MAX__ 4294967295U
+// NVPTX32:#define __UINT32_TYPE__ unsigned int
+// NVPTX32:#define __UINT64_C_SUFFIX__ UL
+// NVPTX32:#define __UINT64_MAX__ 18446744073709551615UL
+// NVPTX32:#define __UINT64_TYPE__ long unsigned int
+// NVPTX32:#define __UINT8_C_SUFFIX__ U
+// NVPTX32:#define __UINT8_MAX__ 255U
+// NVPTX32:#define __UINT8_TYPE__ unsigned char
+// NVPTX32:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // NVPTX32:#define __UINTMAX_TYPE__ long long unsigned int
+// NVPTX32:#define __UINTMAX_WIDTH__ 64
+// NVPTX32:#define __UINTPTR_MAX__ 4294967295U
+// NVPTX32:#define __UINTPTR_TYPE__ unsigned int
+// NVPTX32:#define __UINTPTR_WIDTH__ 32
+// NVPTX32:#define __UINT_FAST16_MAX__ 65535U
+// NVPTX32:#define __UINT_FAST16_TYPE__ unsigned short
+// NVPTX32:#define __UINT_FAST32_MAX__ 4294967295U
+// NVPTX32:#define __UINT_FAST32_TYPE__ unsigned int
+// NVPTX32:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// NVPTX32:#define __UINT_FAST64_TYPE__ long unsigned int
+// NVPTX32:#define __UINT_FAST8_MAX__ 255U
+// NVPTX32:#define __UINT_FAST8_TYPE__ unsigned char
+// NVPTX32:#define __UINT_LEAST16_MAX__ 65535U
+// NVPTX32:#define __UINT_LEAST16_TYPE__ unsigned short
+// NVPTX32:#define __UINT_LEAST32_MAX__ 4294967295U
+// NVPTX32:#define __UINT_LEAST32_TYPE__ unsigned int
+// NVPTX32:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// NVPTX32:#define __UINT_LEAST64_TYPE__ long unsigned int
+// NVPTX32:#define __UINT_LEAST8_MAX__ 255U
+// NVPTX32:#define __UINT_LEAST8_TYPE__ unsigned char
 // NVPTX32:#define __USER_LABEL_PREFIX__ _
 // NVPTX32:#define __WCHAR_MAX__ 2147483647
 // NVPTX32:#define __WCHAR_TYPE__ int
@@ -2255,16 +3215,37 @@
 // NVPTX64:#define __FLT_MIN_EXP__ (-125)
 // NVPTX64:#define __FLT_MIN__ 1.17549435e-38F
 // NVPTX64:#define __FLT_RADIX__ 2
+// NVPTX64:#define __INT16_MAX__ 32767
 // NVPTX64:#define __INT16_TYPE__ short
+// NVPTX64:#define __INT32_MAX__ 2147483647
 // NVPTX64:#define __INT32_TYPE__ int
 // NVPTX64:#define __INT64_C_SUFFIX__ LL
+// NVPTX64:#define __INT64_MAX__ 9223372036854775807L
 // NVPTX64:#define __INT64_TYPE__ long long int
+// NVPTX64:#define __INT8_MAX__ 127
 // NVPTX64:#define __INT8_TYPE__ char
 // NVPTX64:#define __INTMAX_MAX__ 9223372036854775807LL
 // NVPTX64:#define __INTMAX_TYPE__ long long int
 // NVPTX64:#define __INTMAX_WIDTH__ 64
+// NVPTX64:#define __INTPTR_MAX__ 18446744073709551615ULL
 // NVPTX64:#define __INTPTR_TYPE__ long long unsigned int
 // NVPTX64:#define __INTPTR_WIDTH__ 64
+// NVPTX64:#define __INT_FAST16_MAX__ 32767
+// NVPTX64:#define __INT_FAST16_TYPE__ short
+// NVPTX64:#define __INT_FAST32_MAX__ 2147483647
+// NVPTX64:#define __INT_FAST32_TYPE__ int
+// NVPTX64:#define __INT_FAST64_MAX__ 9223372036854775807L
+// NVPTX64:#define __INT_FAST64_TYPE__ long int
+// NVPTX64:#define __INT_FAST8_MAX__ 127
+// NVPTX64:#define __INT_FAST8_TYPE__ char
+// NVPTX64:#define __INT_LEAST16_MAX__ 32767
+// NVPTX64:#define __INT_LEAST16_TYPE__ short
+// NVPTX64:#define __INT_LEAST32_MAX__ 2147483647
+// NVPTX64:#define __INT_LEAST32_TYPE__ int
+// NVPTX64:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// NVPTX64:#define __INT_LEAST64_TYPE__ long int
+// NVPTX64:#define __INT_LEAST8_MAX__ 127
+// NVPTX64:#define __INT_LEAST8_TYPE__ char
 // NVPTX64:#define __INT_MAX__ 2147483647
 // NVPTX64:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // NVPTX64:#define __LDBL_DIG__ 15
@@ -2307,7 +3288,40 @@
 // NVPTX64:#define __SIZE_MAX__ 18446744073709551615UL
 // NVPTX64:#define __SIZE_TYPE__ long long unsigned int
 // NVPTX64:#define __SIZE_WIDTH__ 64
+// NVPTX64:#define __UINT16_C_SUFFIX__ U
+// NVPTX64:#define __UINT16_MAX__ 65535U
+// NVPTX64:#define __UINT16_TYPE__ unsigned short
+// NVPTX64:#define __UINT32_C_SUFFIX__ U
+// NVPTX64:#define __UINT32_MAX__ 4294967295U
+// NVPTX64:#define __UINT32_TYPE__ unsigned int
+// NVPTX64:#define __UINT64_C_SUFFIX__ UL
+// NVPTX64:#define __UINT64_MAX__ 18446744073709551615UL
+// NVPTX64:#define __UINT64_TYPE__ long unsigned int
+// NVPTX64:#define __UINT8_C_SUFFIX__ U
+// NVPTX64:#define __UINT8_MAX__ 255U
+// NVPTX64:#define __UINT8_TYPE__ unsigned char
+// NVPTX64:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // NVPTX64:#define __UINTMAX_TYPE__ long long unsigned int
+// NVPTX64:#define __UINTMAX_WIDTH__ 64
+// NVPTX64:#define __UINTPTR_MAX__ 18446744073709551615UL
+// NVPTX64:#define __UINTPTR_TYPE__ long unsigned int
+// NVPTX64:#define __UINTPTR_WIDTH__ 64
+// NVPTX64:#define __UINT_FAST16_MAX__ 65535U
+// NVPTX64:#define __UINT_FAST16_TYPE__ unsigned short
+// NVPTX64:#define __UINT_FAST32_MAX__ 4294967295U
+// NVPTX64:#define __UINT_FAST32_TYPE__ unsigned int
+// NVPTX64:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// NVPTX64:#define __UINT_FAST64_TYPE__ long unsigned int
+// NVPTX64:#define __UINT_FAST8_MAX__ 255U
+// NVPTX64:#define __UINT_FAST8_TYPE__ unsigned char
+// NVPTX64:#define __UINT_LEAST16_MAX__ 65535U
+// NVPTX64:#define __UINT_LEAST16_TYPE__ unsigned short
+// NVPTX64:#define __UINT_LEAST32_MAX__ 4294967295U
+// NVPTX64:#define __UINT_LEAST32_TYPE__ unsigned int
+// NVPTX64:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// NVPTX64:#define __UINT_LEAST64_TYPE__ long unsigned int
+// NVPTX64:#define __UINT_LEAST8_MAX__ 255U
+// NVPTX64:#define __UINT_LEAST8_TYPE__ unsigned char
 // NVPTX64:#define __USER_LABEL_PREFIX__ _
 // NVPTX64:#define __WCHAR_MAX__ 2147483647
 // NVPTX64:#define __WCHAR_TYPE__ int
@@ -2357,16 +3371,37 @@
 // PPC603E:#define __FLT_MIN_EXP__ (-125)
 // PPC603E:#define __FLT_MIN__ 1.17549435e-38F
 // PPC603E:#define __FLT_RADIX__ 2
+// PPC603E:#define __INT16_MAX__ 32767
 // PPC603E:#define __INT16_TYPE__ short
+// PPC603E:#define __INT32_MAX__ 2147483647
 // PPC603E:#define __INT32_TYPE__ int
 // PPC603E:#define __INT64_C_SUFFIX__ LL
+// PPC603E:#define __INT64_MAX__ 9223372036854775807LL
 // PPC603E:#define __INT64_TYPE__ long long int
+// PPC603E:#define __INT8_MAX__ 127
 // PPC603E:#define __INT8_TYPE__ char
 // PPC603E:#define __INTMAX_MAX__ 9223372036854775807LL
 // PPC603E:#define __INTMAX_TYPE__ long long int
 // PPC603E:#define __INTMAX_WIDTH__ 64
+// PPC603E:#define __INTPTR_MAX__ 2147483647L
 // PPC603E:#define __INTPTR_TYPE__ long int
 // PPC603E:#define __INTPTR_WIDTH__ 32
+// PPC603E:#define __INT_FAST16_MAX__ 32767
+// PPC603E:#define __INT_FAST16_TYPE__ short
+// PPC603E:#define __INT_FAST32_MAX__ 2147483647
+// PPC603E:#define __INT_FAST32_TYPE__ int
+// PPC603E:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC603E:#define __INT_FAST64_TYPE__ long long int
+// PPC603E:#define __INT_FAST8_MAX__ 127
+// PPC603E:#define __INT_FAST8_TYPE__ char
+// PPC603E:#define __INT_LEAST16_MAX__ 32767
+// PPC603E:#define __INT_LEAST16_TYPE__ short
+// PPC603E:#define __INT_LEAST32_MAX__ 2147483647
+// PPC603E:#define __INT_LEAST32_TYPE__ int
+// PPC603E:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC603E:#define __INT_LEAST64_TYPE__ long long int
+// PPC603E:#define __INT_LEAST8_MAX__ 127
+// PPC603E:#define __INT_LEAST8_TYPE__ char
 // PPC603E:#define __INT_MAX__ 2147483647
 // PPC603E:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC603E:#define __LDBL_DIG__ 31
@@ -2410,7 +3445,40 @@
 // PPC603E:#define __SIZE_MAX__ 4294967295U
 // PPC603E:#define __SIZE_TYPE__ long unsigned int
 // PPC603E:#define __SIZE_WIDTH__ 32
+// PPC603E:#define __UINT16_C_SUFFIX__ U
+// PPC603E:#define __UINT16_MAX__ 65535U
+// PPC603E:#define __UINT16_TYPE__ unsigned short
+// PPC603E:#define __UINT32_C_SUFFIX__ U
+// PPC603E:#define __UINT32_MAX__ 4294967295U
+// PPC603E:#define __UINT32_TYPE__ unsigned int
+// PPC603E:#define __UINT64_C_SUFFIX__ ULL
+// PPC603E:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC603E:#define __UINT64_TYPE__ long long unsigned int
+// PPC603E:#define __UINT8_C_SUFFIX__ U
+// PPC603E:#define __UINT8_MAX__ 255U
+// PPC603E:#define __UINT8_TYPE__ unsigned char
+// PPC603E:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // PPC603E:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC603E:#define __UINTMAX_WIDTH__ 64
+// PPC603E:#define __UINTPTR_MAX__ 4294967295U
+// PPC603E:#define __UINTPTR_TYPE__ unsigned int
+// PPC603E:#define __UINTPTR_WIDTH__ 32
+// PPC603E:#define __UINT_FAST16_MAX__ 65535U
+// PPC603E:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC603E:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC603E:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC603E:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC603E:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC603E:#define __UINT_FAST8_MAX__ 255U
+// PPC603E:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC603E:#define __UINT_LEAST16_MAX__ 65535U
+// PPC603E:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC603E:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC603E:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC603E:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC603E:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC603E:#define __UINT_LEAST8_MAX__ 255U
+// PPC603E:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC603E:#define __USER_LABEL_PREFIX__ _
 // PPC603E:#define __WCHAR_MAX__ 2147483647
 // PPC603E:#define __WCHAR_TYPE__ int
@@ -2467,16 +3535,37 @@
 // PPC64:#define __FLT_MIN_EXP__ (-125)
 // PPC64:#define __FLT_MIN__ 1.17549435e-38F
 // PPC64:#define __FLT_RADIX__ 2
+// PPC64:#define __INT16_MAX__ 32767
 // PPC64:#define __INT16_TYPE__ short
+// PPC64:#define __INT32_MAX__ 2147483647
 // PPC64:#define __INT32_TYPE__ int
 // PPC64:#define __INT64_C_SUFFIX__ L
+// PPC64:#define __INT64_MAX__ 9223372036854775807L
 // PPC64:#define __INT64_TYPE__ long int
+// PPC64:#define __INT8_MAX__ 127
 // PPC64:#define __INT8_TYPE__ char
 // PPC64:#define __INTMAX_MAX__ 9223372036854775807L
 // PPC64:#define __INTMAX_TYPE__ long int
 // PPC64:#define __INTMAX_WIDTH__ 64
+// PPC64:#define __INTPTR_MAX__ 9223372036854775807L
 // PPC64:#define __INTPTR_TYPE__ long int
 // PPC64:#define __INTPTR_WIDTH__ 64
+// PPC64:#define __INT_FAST16_MAX__ 32767
+// PPC64:#define __INT_FAST16_TYPE__ short
+// PPC64:#define __INT_FAST32_MAX__ 2147483647
+// PPC64:#define __INT_FAST32_TYPE__ int
+// PPC64:#define __INT_FAST64_MAX__ 9223372036854775807L
+// PPC64:#define __INT_FAST64_TYPE__ long int
+// PPC64:#define __INT_FAST8_MAX__ 127
+// PPC64:#define __INT_FAST8_TYPE__ char
+// PPC64:#define __INT_LEAST16_MAX__ 32767
+// PPC64:#define __INT_LEAST16_TYPE__ short
+// PPC64:#define __INT_LEAST32_MAX__ 2147483647
+// PPC64:#define __INT_LEAST32_TYPE__ int
+// PPC64:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// PPC64:#define __INT_LEAST64_TYPE__ long int
+// PPC64:#define __INT_LEAST8_MAX__ 127
+// PPC64:#define __INT_LEAST8_TYPE__ char
 // PPC64:#define __INT_MAX__ 2147483647
 // PPC64:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC64:#define __LDBL_DIG__ 31
@@ -2521,7 +3610,40 @@
 // PPC64:#define __SIZE_MAX__ 18446744073709551615UL
 // PPC64:#define __SIZE_TYPE__ long unsigned int
 // PPC64:#define __SIZE_WIDTH__ 64
+// PPC64:#define __UINT16_C_SUFFIX__ U
+// PPC64:#define __UINT16_MAX__ 65535U
+// PPC64:#define __UINT16_TYPE__ unsigned short
+// PPC64:#define __UINT32_C_SUFFIX__ U
+// PPC64:#define __UINT32_MAX__ 4294967295U
+// PPC64:#define __UINT32_TYPE__ unsigned int
+// PPC64:#define __UINT64_C_SUFFIX__ UL
+// PPC64:#define __UINT64_MAX__ 18446744073709551615UL
+// PPC64:#define __UINT64_TYPE__ long unsigned int
+// PPC64:#define __UINT8_C_SUFFIX__ U
+// PPC64:#define __UINT8_MAX__ 255U
+// PPC64:#define __UINT8_TYPE__ unsigned char
+// PPC64:#define __UINTMAX_MAX__ 18446744073709551615UL
 // PPC64:#define __UINTMAX_TYPE__ long unsigned int
+// PPC64:#define __UINTMAX_WIDTH__ 64
+// PPC64:#define __UINTPTR_MAX__ 18446744073709551615UL
+// PPC64:#define __UINTPTR_TYPE__ long unsigned int
+// PPC64:#define __UINTPTR_WIDTH__ 64
+// PPC64:#define __UINT_FAST16_MAX__ 65535U
+// PPC64:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC64:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC64:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC64:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// PPC64:#define __UINT_FAST64_TYPE__ long unsigned int
+// PPC64:#define __UINT_FAST8_MAX__ 255U
+// PPC64:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC64:#define __UINT_LEAST16_MAX__ 65535U
+// PPC64:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC64:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC64:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC64:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// PPC64:#define __UINT_LEAST64_TYPE__ long unsigned int
+// PPC64:#define __UINT_LEAST8_MAX__ 255U
+// PPC64:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC64:#define __USER_LABEL_PREFIX__ _
 // PPC64:#define __WCHAR_MAX__ 2147483647
 // PPC64:#define __WCHAR_TYPE__ int
@@ -2580,16 +3702,37 @@
 // PPC64LE:#define __FLT_MIN_EXP__ (-125)
 // PPC64LE:#define __FLT_MIN__ 1.17549435e-38F
 // PPC64LE:#define __FLT_RADIX__ 2
+// PPC64LE:#define __INT16_MAX__ 32767
 // PPC64LE:#define __INT16_TYPE__ short
+// PPC64LE:#define __INT32_MAX__ 2147483647
 // PPC64LE:#define __INT32_TYPE__ int
 // PPC64LE:#define __INT64_C_SUFFIX__ L
+// PPC64LE:#define __INT64_MAX__ 9223372036854775807L
 // PPC64LE:#define __INT64_TYPE__ long int
+// PPC64LE:#define __INT8_MAX__ 127
 // PPC64LE:#define __INT8_TYPE__ char
 // PPC64LE:#define __INTMAX_MAX__ 9223372036854775807L
 // PPC64LE:#define __INTMAX_TYPE__ long int
 // PPC64LE:#define __INTMAX_WIDTH__ 64
+// PPC64LE:#define __INTPTR_MAX__ 9223372036854775807L
 // PPC64LE:#define __INTPTR_TYPE__ long int
 // PPC64LE:#define __INTPTR_WIDTH__ 64
+// PPC64LE:#define __INT_FAST16_MAX__ 32767
+// PPC64LE:#define __INT_FAST16_TYPE__ short
+// PPC64LE:#define __INT_FAST32_MAX__ 2147483647
+// PPC64LE:#define __INT_FAST32_TYPE__ int
+// PPC64LE:#define __INT_FAST64_MAX__ 9223372036854775807L
+// PPC64LE:#define __INT_FAST64_TYPE__ long int
+// PPC64LE:#define __INT_FAST8_MAX__ 127
+// PPC64LE:#define __INT_FAST8_TYPE__ char
+// PPC64LE:#define __INT_LEAST16_MAX__ 32767
+// PPC64LE:#define __INT_LEAST16_TYPE__ short
+// PPC64LE:#define __INT_LEAST32_MAX__ 2147483647
+// PPC64LE:#define __INT_LEAST32_TYPE__ int
+// PPC64LE:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// PPC64LE:#define __INT_LEAST64_TYPE__ long int
+// PPC64LE:#define __INT_LEAST8_MAX__ 127
+// PPC64LE:#define __INT_LEAST8_TYPE__ char
 // PPC64LE:#define __INT_MAX__ 2147483647
 // PPC64LE:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC64LE:#define __LDBL_DIG__ 31
@@ -2635,7 +3778,40 @@
 // PPC64LE:#define __SIZE_MAX__ 18446744073709551615UL
 // PPC64LE:#define __SIZE_TYPE__ long unsigned int
 // PPC64LE:#define __SIZE_WIDTH__ 64
+// PPC64LE:#define __UINT16_C_SUFFIX__ U
+// PPC64LE:#define __UINT16_MAX__ 65535U
+// PPC64LE:#define __UINT16_TYPE__ unsigned short
+// PPC64LE:#define __UINT32_C_SUFFIX__ U
+// PPC64LE:#define __UINT32_MAX__ 4294967295U
+// PPC64LE:#define __UINT32_TYPE__ unsigned int
+// PPC64LE:#define __UINT64_C_SUFFIX__ UL
+// PPC64LE:#define __UINT64_MAX__ 18446744073709551615UL
+// PPC64LE:#define __UINT64_TYPE__ long unsigned int
+// PPC64LE:#define __UINT8_C_SUFFIX__ U
+// PPC64LE:#define __UINT8_MAX__ 255U
+// PPC64LE:#define __UINT8_TYPE__ unsigned char
+// PPC64LE:#define __UINTMAX_MAX__ 18446744073709551615UL
 // PPC64LE:#define __UINTMAX_TYPE__ long unsigned int
+// PPC64LE:#define __UINTMAX_WIDTH__ 64
+// PPC64LE:#define __UINTPTR_MAX__ 18446744073709551615UL
+// PPC64LE:#define __UINTPTR_TYPE__ long unsigned int
+// PPC64LE:#define __UINTPTR_WIDTH__ 64
+// PPC64LE:#define __UINT_FAST16_MAX__ 65535U
+// PPC64LE:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC64LE:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC64LE:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC64LE:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// PPC64LE:#define __UINT_FAST64_TYPE__ long unsigned int
+// PPC64LE:#define __UINT_FAST8_MAX__ 255U
+// PPC64LE:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC64LE:#define __UINT_LEAST16_MAX__ 65535U
+// PPC64LE:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC64LE:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC64LE:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC64LE:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// PPC64LE:#define __UINT_LEAST64_TYPE__ long unsigned int
+// PPC64LE:#define __UINT_LEAST8_MAX__ 255U
+// PPC64LE:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC64LE:#define __USER_LABEL_PREFIX__ _
 // PPC64LE:#define __WCHAR_MAX__ 2147483647
 // PPC64LE:#define __WCHAR_TYPE__ int
@@ -2805,6 +3981,34 @@
 // PPCPOWER7:#define _ARCH_PWR6X 1
 // PPCPOWER7:#define _ARCH_PWR7 1
 //
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPCPWR8 %s
+//
+// PPCPWR8:#define _ARCH_PPC 1
+// PPCPWR8:#define _ARCH_PPC64 1
+// PPCPWR8:#define _ARCH_PPCGR 1
+// PPCPWR8:#define _ARCH_PPCSQ 1
+// PPCPWR8:#define _ARCH_PWR4 1
+// PPCPWR8:#define _ARCH_PWR5 1
+// PPCPWR8:#define _ARCH_PWR5X 1
+// PPCPWR8:#define _ARCH_PWR6 1
+// PPCPWR8:#define _ARCH_PWR6X 1
+// PPCPWR8:#define _ARCH_PWR7 1
+// PPCPWR8:#define _ARCH_PWR8 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPCPOWER8 %s
+//
+// PPCPOWER8:#define _ARCH_PPC 1
+// PPCPOWER8:#define _ARCH_PPC64 1
+// PPCPOWER8:#define _ARCH_PPCGR 1
+// PPCPOWER8:#define _ARCH_PPCSQ 1
+// PPCPOWER8:#define _ARCH_PWR4 1
+// PPCPOWER8:#define _ARCH_PWR5 1
+// PPCPOWER8:#define _ARCH_PWR5X 1
+// PPCPOWER8:#define _ARCH_PWR6 1
+// PPCPOWER8:#define _ARCH_PWR6X 1
+// PPCPOWER8:#define _ARCH_PWR7 1
+// PPCPOWER8:#define _ARCH_PWR8 1
+//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -check-prefix PPC64-LINUX %s
 //
 // PPC64-LINUX:#define _ARCH_PPC 1
@@ -2846,16 +4050,37 @@
 // PPC64-LINUX:#define __FLT_MIN_EXP__ (-125)
 // PPC64-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // PPC64-LINUX:#define __FLT_RADIX__ 2
+// PPC64-LINUX:#define __INT16_MAX__ 32767
 // PPC64-LINUX:#define __INT16_TYPE__ short
+// PPC64-LINUX:#define __INT32_MAX__ 2147483647
 // PPC64-LINUX:#define __INT32_TYPE__ int
 // PPC64-LINUX:#define __INT64_C_SUFFIX__ L
+// PPC64-LINUX:#define __INT64_MAX__ 9223372036854775807L
 // PPC64-LINUX:#define __INT64_TYPE__ long int
+// PPC64-LINUX:#define __INT8_MAX__ 127
 // PPC64-LINUX:#define __INT8_TYPE__ char
 // PPC64-LINUX:#define __INTMAX_MAX__ 9223372036854775807L
 // PPC64-LINUX:#define __INTMAX_TYPE__ long int
 // PPC64-LINUX:#define __INTMAX_WIDTH__ 64
+// PPC64-LINUX:#define __INTPTR_MAX__ 9223372036854775807L
 // PPC64-LINUX:#define __INTPTR_TYPE__ long int
 // PPC64-LINUX:#define __INTPTR_WIDTH__ 64
+// PPC64-LINUX:#define __INT_FAST16_MAX__ 32767
+// PPC64-LINUX:#define __INT_FAST16_TYPE__ short
+// PPC64-LINUX:#define __INT_FAST32_MAX__ 2147483647
+// PPC64-LINUX:#define __INT_FAST32_TYPE__ int
+// PPC64-LINUX:#define __INT_FAST64_MAX__ 9223372036854775807L
+// PPC64-LINUX:#define __INT_FAST64_TYPE__ long int
+// PPC64-LINUX:#define __INT_FAST8_MAX__ 127
+// PPC64-LINUX:#define __INT_FAST8_TYPE__ char
+// PPC64-LINUX:#define __INT_LEAST16_MAX__ 32767
+// PPC64-LINUX:#define __INT_LEAST16_TYPE__ short
+// PPC64-LINUX:#define __INT_LEAST32_MAX__ 2147483647
+// PPC64-LINUX:#define __INT_LEAST32_TYPE__ int
+// PPC64-LINUX:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// PPC64-LINUX:#define __INT_LEAST64_TYPE__ long int
+// PPC64-LINUX:#define __INT_LEAST8_MAX__ 127
+// PPC64-LINUX:#define __INT_LEAST8_TYPE__ char
 // PPC64-LINUX:#define __INT_MAX__ 2147483647
 // PPC64-LINUX:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC64-LINUX:#define __LDBL_DIG__ 31
@@ -2900,7 +4125,40 @@
 // PPC64-LINUX:#define __SIZE_MAX__ 18446744073709551615UL
 // PPC64-LINUX:#define __SIZE_TYPE__ long unsigned int
 // PPC64-LINUX:#define __SIZE_WIDTH__ 64
+// PPC64-LINUX:#define __UINT16_C_SUFFIX__ U
+// PPC64-LINUX:#define __UINT16_MAX__ 65535U
+// PPC64-LINUX:#define __UINT16_TYPE__ unsigned short
+// PPC64-LINUX:#define __UINT32_C_SUFFIX__ U
+// PPC64-LINUX:#define __UINT32_MAX__ 4294967295U
+// PPC64-LINUX:#define __UINT32_TYPE__ unsigned int
+// PPC64-LINUX:#define __UINT64_C_SUFFIX__ UL
+// PPC64-LINUX:#define __UINT64_MAX__ 18446744073709551615UL
+// PPC64-LINUX:#define __UINT64_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINT8_C_SUFFIX__ U
+// PPC64-LINUX:#define __UINT8_MAX__ 255U
+// PPC64-LINUX:#define __UINT8_TYPE__ unsigned char
+// PPC64-LINUX:#define __UINTMAX_MAX__ 18446744073709551615UL
 // PPC64-LINUX:#define __UINTMAX_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINTMAX_WIDTH__ 64
+// PPC64-LINUX:#define __UINTPTR_MAX__ 18446744073709551615UL
+// PPC64-LINUX:#define __UINTPTR_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINTPTR_WIDTH__ 64
+// PPC64-LINUX:#define __UINT_FAST16_MAX__ 65535U
+// PPC64-LINUX:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC64-LINUX:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC64-LINUX:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC64-LINUX:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// PPC64-LINUX:#define __UINT_FAST64_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINT_FAST8_MAX__ 255U
+// PPC64-LINUX:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC64-LINUX:#define __UINT_LEAST16_MAX__ 65535U
+// PPC64-LINUX:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC64-LINUX:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC64-LINUX:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC64-LINUX:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// PPC64-LINUX:#define __UINT_LEAST64_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINT_LEAST8_MAX__ 255U
+// PPC64-LINUX:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC64-LINUX:#define __USER_LABEL_PREFIX__
 // PPC64-LINUX:#define __WCHAR_MAX__ 2147483647
 // PPC64-LINUX:#define __WCHAR_TYPE__ int
@@ -2953,16 +4211,37 @@
 // PPC:#define __FLT_MIN_EXP__ (-125)
 // PPC:#define __FLT_MIN__ 1.17549435e-38F
 // PPC:#define __FLT_RADIX__ 2
+// PPC:#define __INT16_MAX__ 32767
 // PPC:#define __INT16_TYPE__ short
+// PPC:#define __INT32_MAX__ 2147483647
 // PPC:#define __INT32_TYPE__ int
 // PPC:#define __INT64_C_SUFFIX__ LL
+// PPC:#define __INT64_MAX__ 9223372036854775807LL
 // PPC:#define __INT64_TYPE__ long long int
+// PPC:#define __INT8_MAX__ 127
 // PPC:#define __INT8_TYPE__ char
 // PPC:#define __INTMAX_MAX__ 9223372036854775807LL
 // PPC:#define __INTMAX_TYPE__ long long int
 // PPC:#define __INTMAX_WIDTH__ 64
+// PPC:#define __INTPTR_MAX__ 2147483647L
 // PPC:#define __INTPTR_TYPE__ long int
 // PPC:#define __INTPTR_WIDTH__ 32
+// PPC:#define __INT_FAST16_MAX__ 32767
+// PPC:#define __INT_FAST16_TYPE__ short
+// PPC:#define __INT_FAST32_MAX__ 2147483647
+// PPC:#define __INT_FAST32_TYPE__ int
+// PPC:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC:#define __INT_FAST64_TYPE__ long long int
+// PPC:#define __INT_FAST8_MAX__ 127
+// PPC:#define __INT_FAST8_TYPE__ char
+// PPC:#define __INT_LEAST16_MAX__ 32767
+// PPC:#define __INT_LEAST16_TYPE__ short
+// PPC:#define __INT_LEAST32_MAX__ 2147483647
+// PPC:#define __INT_LEAST32_TYPE__ int
+// PPC:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC:#define __INT_LEAST64_TYPE__ long long int
+// PPC:#define __INT_LEAST8_MAX__ 127
+// PPC:#define __INT_LEAST8_TYPE__ char
 // PPC:#define __INT_MAX__ 2147483647
 // PPC:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC:#define __LDBL_DIG__ 31
@@ -3006,7 +4285,40 @@
 // PPC:#define __SIZE_MAX__ 4294967295U
 // PPC:#define __SIZE_TYPE__ long unsigned int
 // PPC:#define __SIZE_WIDTH__ 32
+// PPC:#define __UINT16_C_SUFFIX__ U
+// PPC:#define __UINT16_MAX__ 65535U
+// PPC:#define __UINT16_TYPE__ unsigned short
+// PPC:#define __UINT32_C_SUFFIX__ U
+// PPC:#define __UINT32_MAX__ 4294967295U
+// PPC:#define __UINT32_TYPE__ unsigned int
+// PPC:#define __UINT64_C_SUFFIX__ ULL
+// PPC:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC:#define __UINT64_TYPE__ long long unsigned int
+// PPC:#define __UINT8_C_SUFFIX__ U
+// PPC:#define __UINT8_MAX__ 255U
+// PPC:#define __UINT8_TYPE__ unsigned char
+// PPC:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // PPC:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC:#define __UINTMAX_WIDTH__ 64
+// PPC:#define __UINTPTR_MAX__ 4294967295U
+// PPC:#define __UINTPTR_TYPE__ unsigned int
+// PPC:#define __UINTPTR_WIDTH__ 32
+// PPC:#define __UINT_FAST16_MAX__ 65535U
+// PPC:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC:#define __UINT_FAST8_MAX__ 255U
+// PPC:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC:#define __UINT_LEAST16_MAX__ 65535U
+// PPC:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC:#define __UINT_LEAST8_MAX__ 255U
+// PPC:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC:#define __USER_LABEL_PREFIX__ _
 // PPC:#define __WCHAR_MAX__ 2147483647
 // PPC:#define __WCHAR_TYPE__ int
@@ -3055,16 +4367,37 @@
 // PPC-LINUX:#define __FLT_MIN_EXP__ (-125)
 // PPC-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // PPC-LINUX:#define __FLT_RADIX__ 2
+// PPC-LINUX:#define __INT16_MAX__ 32767
 // PPC-LINUX:#define __INT16_TYPE__ short
+// PPC-LINUX:#define __INT32_MAX__ 2147483647
 // PPC-LINUX:#define __INT32_TYPE__ int
 // PPC-LINUX:#define __INT64_C_SUFFIX__ LL
+// PPC-LINUX:#define __INT64_MAX__ 9223372036854775807LL
 // PPC-LINUX:#define __INT64_TYPE__ long long int
+// PPC-LINUX:#define __INT8_MAX__ 127
 // PPC-LINUX:#define __INT8_TYPE__ char
 // PPC-LINUX:#define __INTMAX_MAX__ 9223372036854775807LL
 // PPC-LINUX:#define __INTMAX_TYPE__ long long int
 // PPC-LINUX:#define __INTMAX_WIDTH__ 64
+// PPC-LINUX:#define __INTPTR_MAX__ 2147483647
 // PPC-LINUX:#define __INTPTR_TYPE__ int
 // PPC-LINUX:#define __INTPTR_WIDTH__ 32
+// PPC-LINUX:#define __INT_FAST16_MAX__ 32767
+// PPC-LINUX:#define __INT_FAST16_TYPE__ short
+// PPC-LINUX:#define __INT_FAST32_MAX__ 2147483647
+// PPC-LINUX:#define __INT_FAST32_TYPE__ int
+// PPC-LINUX:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC-LINUX:#define __INT_FAST64_TYPE__ long long int
+// PPC-LINUX:#define __INT_FAST8_MAX__ 127
+// PPC-LINUX:#define __INT_FAST8_TYPE__ char
+// PPC-LINUX:#define __INT_LEAST16_MAX__ 32767
+// PPC-LINUX:#define __INT_LEAST16_TYPE__ short
+// PPC-LINUX:#define __INT_LEAST32_MAX__ 2147483647
+// PPC-LINUX:#define __INT_LEAST32_TYPE__ int
+// PPC-LINUX:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC-LINUX:#define __INT_LEAST64_TYPE__ long long int
+// PPC-LINUX:#define __INT_LEAST8_MAX__ 127
+// PPC-LINUX:#define __INT_LEAST8_TYPE__ char
 // PPC-LINUX:#define __INT_MAX__ 2147483647
 // PPC-LINUX:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC-LINUX:#define __LDBL_DIG__ 31
@@ -3108,7 +4441,40 @@
 // PPC-LINUX:#define __SIZE_MAX__ 4294967295U
 // PPC-LINUX:#define __SIZE_TYPE__ unsigned int
 // PPC-LINUX:#define __SIZE_WIDTH__ 32
+// PPC-LINUX:#define __UINT16_C_SUFFIX__ U
+// PPC-LINUX:#define __UINT16_MAX__ 65535U
+// PPC-LINUX:#define __UINT16_TYPE__ unsigned short
+// PPC-LINUX:#define __UINT32_C_SUFFIX__ U
+// PPC-LINUX:#define __UINT32_MAX__ 4294967295U
+// PPC-LINUX:#define __UINT32_TYPE__ unsigned int
+// PPC-LINUX:#define __UINT64_C_SUFFIX__ ULL
+// PPC-LINUX:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC-LINUX:#define __UINT64_TYPE__ long long unsigned int
+// PPC-LINUX:#define __UINT8_C_SUFFIX__ U
+// PPC-LINUX:#define __UINT8_MAX__ 255U
+// PPC-LINUX:#define __UINT8_TYPE__ unsigned char
+// PPC-LINUX:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // PPC-LINUX:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC-LINUX:#define __UINTMAX_WIDTH__ 64
+// PPC-LINUX:#define __UINTPTR_MAX__ 4294967295U
+// PPC-LINUX:#define __UINTPTR_TYPE__ unsigned int
+// PPC-LINUX:#define __UINTPTR_WIDTH__ 32
+// PPC-LINUX:#define __UINT_FAST16_MAX__ 65535U
+// PPC-LINUX:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC-LINUX:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC-LINUX:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC-LINUX:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC-LINUX:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC-LINUX:#define __UINT_FAST8_MAX__ 255U
+// PPC-LINUX:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC-LINUX:#define __UINT_LEAST16_MAX__ 65535U
+// PPC-LINUX:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC-LINUX:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC-LINUX:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC-LINUX:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC-LINUX:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC-LINUX:#define __UINT_LEAST8_MAX__ 255U
+// PPC-LINUX:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC-LINUX:#define __USER_LABEL_PREFIX__
 // PPC-LINUX:#define __WCHAR_MAX__ 2147483647
 // PPC-LINUX:#define __WCHAR_TYPE__ int
@@ -3157,16 +4523,37 @@
 // PPC-DARWIN:#define __FLT_MIN_EXP__ (-125)
 // PPC-DARWIN:#define __FLT_MIN__ 1.17549435e-38F
 // PPC-DARWIN:#define __FLT_RADIX__ 2
+// PPC-DARWIN:#define __INT16_MAX__ 32767
 // PPC-DARWIN:#define __INT16_TYPE__ short
+// PPC-DARWIN:#define __INT32_MAX__ 2147483647
 // PPC-DARWIN:#define __INT32_TYPE__ int
 // PPC-DARWIN:#define __INT64_C_SUFFIX__ LL
+// PPC-DARWIN:#define __INT64_MAX__ 9223372036854775807LL
 // PPC-DARWIN:#define __INT64_TYPE__ long long int
+// PPC-DARWIN:#define __INT8_MAX__ 127
 // PPC-DARWIN:#define __INT8_TYPE__ char
 // PPC-DARWIN:#define __INTMAX_MAX__ 9223372036854775807LL
 // PPC-DARWIN:#define __INTMAX_TYPE__ long long int
 // PPC-DARWIN:#define __INTMAX_WIDTH__ 64
+// PPC-DARWIN:#define __INTPTR_MAX__ 2147483647L
 // PPC-DARWIN:#define __INTPTR_TYPE__ long int
 // PPC-DARWIN:#define __INTPTR_WIDTH__ 32
+// PPC-DARWIN:#define __INT_FAST16_MAX__ 32767
+// PPC-DARWIN:#define __INT_FAST16_TYPE__ short
+// PPC-DARWIN:#define __INT_FAST32_MAX__ 2147483647
+// PPC-DARWIN:#define __INT_FAST32_TYPE__ int
+// PPC-DARWIN:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC-DARWIN:#define __INT_FAST64_TYPE__ long long int
+// PPC-DARWIN:#define __INT_FAST8_MAX__ 127
+// PPC-DARWIN:#define __INT_FAST8_TYPE__ char
+// PPC-DARWIN:#define __INT_LEAST16_MAX__ 32767
+// PPC-DARWIN:#define __INT_LEAST16_TYPE__ short
+// PPC-DARWIN:#define __INT_LEAST32_MAX__ 2147483647
+// PPC-DARWIN:#define __INT_LEAST32_TYPE__ int
+// PPC-DARWIN:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC-DARWIN:#define __INT_LEAST64_TYPE__ long long int
+// PPC-DARWIN:#define __INT_LEAST8_MAX__ 127
+// PPC-DARWIN:#define __INT_LEAST8_TYPE__ char
 // PPC-DARWIN:#define __INT_MAX__ 2147483647
 // PPC-DARWIN:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC-DARWIN:#define __LDBL_DIG__ 31
@@ -3216,7 +4603,40 @@
 // PPC-DARWIN:#define __STDC_HOSTED__ 0
 // PPC-DARWIN:#define __STDC_VERSION__ 199901L
 // PPC-DARWIN:#define __STDC__ 1
+// PPC-DARWIN:#define __UINT16_C_SUFFIX__ U
+// PPC-DARWIN:#define __UINT16_MAX__ 65535U
+// PPC-DARWIN:#define __UINT16_TYPE__ unsigned short
+// PPC-DARWIN:#define __UINT32_C_SUFFIX__ U
+// PPC-DARWIN:#define __UINT32_MAX__ 4294967295U
+// PPC-DARWIN:#define __UINT32_TYPE__ unsigned int
+// PPC-DARWIN:#define __UINT64_C_SUFFIX__ ULL
+// PPC-DARWIN:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC-DARWIN:#define __UINT64_TYPE__ long long unsigned int
+// PPC-DARWIN:#define __UINT8_C_SUFFIX__ U
+// PPC-DARWIN:#define __UINT8_MAX__ 255U
+// PPC-DARWIN:#define __UINT8_TYPE__ unsigned char
+// PPC-DARWIN:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // PPC-DARWIN:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC-DARWIN:#define __UINTMAX_WIDTH__ 64
+// PPC-DARWIN:#define __UINTPTR_MAX__ 4294967295U
+// PPC-DARWIN:#define __UINTPTR_TYPE__ unsigned int
+// PPC-DARWIN:#define __UINTPTR_WIDTH__ 32
+// PPC-DARWIN:#define __UINT_FAST16_MAX__ 65535U
+// PPC-DARWIN:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC-DARWIN:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC-DARWIN:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC-DARWIN:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC-DARWIN:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC-DARWIN:#define __UINT_FAST8_MAX__ 255U
+// PPC-DARWIN:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC-DARWIN:#define __UINT_LEAST16_MAX__ 65535U
+// PPC-DARWIN:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC-DARWIN:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC-DARWIN:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC-DARWIN:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC-DARWIN:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC-DARWIN:#define __UINT_LEAST8_MAX__ 255U
+// PPC-DARWIN:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC-DARWIN:#define __USER_LABEL_PREFIX__ _
 // PPC-DARWIN:#define __WCHAR_MAX__ 2147483647
 // PPC-DARWIN:#define __WCHAR_TYPE__ int
@@ -3261,16 +4681,37 @@
 // S390X:#define __FLT_MIN_EXP__ (-125)
 // S390X:#define __FLT_MIN__ 1.17549435e-38F
 // S390X:#define __FLT_RADIX__ 2
+// S390X:#define __INT16_MAX__ 32767
 // S390X:#define __INT16_TYPE__ short
+// S390X:#define __INT32_MAX__ 2147483647
 // S390X:#define __INT32_TYPE__ int
-// S390X:#define __INT64_C_SUFFIX__ L
+// S390X:#define __INT64_C_SUFFIX__ LL
+// S390X:#define __INT64_MAX__ 9223372036854775807LL
 // S390X:#define __INT64_TYPE__ long long int
+// S390X:#define __INT8_MAX__ 127
 // S390X:#define __INT8_TYPE__ char
 // S390X:#define __INTMAX_MAX__ 9223372036854775807LL
 // S390X:#define __INTMAX_TYPE__ long long int
 // S390X:#define __INTMAX_WIDTH__ 64
+// S390X:#define __INTPTR_MAX__ 9223372036854775807L
 // S390X:#define __INTPTR_TYPE__ long int
 // S390X:#define __INTPTR_WIDTH__ 64
+// S390X:#define __INT_FAST16_MAX__ 32767
+// S390X:#define __INT_FAST16_TYPE__ short
+// S390X:#define __INT_FAST32_MAX__ 2147483647
+// S390X:#define __INT_FAST32_TYPE__ int
+// S390X:#define __INT_FAST64_MAX__ 9223372036854775807L
+// S390X:#define __INT_FAST64_TYPE__ long int
+// S390X:#define __INT_FAST8_MAX__ 127
+// S390X:#define __INT_FAST8_TYPE__ char
+// S390X:#define __INT_LEAST16_MAX__ 32767
+// S390X:#define __INT_LEAST16_TYPE__ short
+// S390X:#define __INT_LEAST32_MAX__ 2147483647
+// S390X:#define __INT_LEAST32_TYPE__ int
+// S390X:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// S390X:#define __INT_LEAST64_TYPE__ long int
+// S390X:#define __INT_LEAST8_MAX__ 127
+// S390X:#define __INT_LEAST8_TYPE__ char
 // S390X:#define __INT_MAX__ 2147483647
 // S390X:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // S390X:#define __LDBL_DIG__ 33
@@ -3308,7 +4749,40 @@
 // S390X:#define __SIZEOF_WINT_T__ 4
 // S390X:#define __SIZE_TYPE__ long unsigned int
 // S390X:#define __SIZE_WIDTH__ 64
+// S390X:#define __UINT16_C_SUFFIX__ U
+// S390X:#define __UINT16_MAX__ 65535U
+// S390X:#define __UINT16_TYPE__ unsigned short
+// S390X:#define __UINT32_C_SUFFIX__ U
+// S390X:#define __UINT32_MAX__ 4294967295U
+// S390X:#define __UINT32_TYPE__ unsigned int
+// S390X:#define __UINT64_C_SUFFIX__ UL
+// S390X:#define __UINT64_MAX__ 18446744073709551615UL
+// S390X:#define __UINT64_TYPE__ long unsigned int
+// S390X:#define __UINT8_C_SUFFIX__ U
+// S390X:#define __UINT8_MAX__ 255U
+// S390X:#define __UINT8_TYPE__ unsigned char
+// S390X:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // S390X:#define __UINTMAX_TYPE__ long long unsigned int
+// S390X:#define __UINTMAX_WIDTH__ 64
+// S390X:#define __UINTPTR_MAX__ 18446744073709551615UL
+// S390X:#define __UINTPTR_TYPE__ long unsigned int
+// S390X:#define __UINTPTR_WIDTH__ 64
+// S390X:#define __UINT_FAST16_MAX__ 65535U
+// S390X:#define __UINT_FAST16_TYPE__ unsigned short
+// S390X:#define __UINT_FAST32_MAX__ 4294967295U
+// S390X:#define __UINT_FAST32_TYPE__ unsigned int
+// S390X:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// S390X:#define __UINT_FAST64_TYPE__ long unsigned int
+// S390X:#define __UINT_FAST8_MAX__ 255U
+// S390X:#define __UINT_FAST8_TYPE__ unsigned char
+// S390X:#define __UINT_LEAST16_MAX__ 65535U
+// S390X:#define __UINT_LEAST16_TYPE__ unsigned short
+// S390X:#define __UINT_LEAST32_MAX__ 4294967295U
+// S390X:#define __UINT_LEAST32_TYPE__ unsigned int
+// S390X:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// S390X:#define __UINT_LEAST64_TYPE__ long unsigned int
+// S390X:#define __UINT_LEAST8_MAX__ 255U
+// S390X:#define __UINT_LEAST8_TYPE__ unsigned char
 // S390X:#define __USER_LABEL_PREFIX__ _
 // S390X:#define __WCHAR_MAX__ 2147483647
 // S390X:#define __WCHAR_TYPE__ int
@@ -3355,16 +4829,37 @@
 // SPARC:#define __FLT_MIN_EXP__ (-125)
 // SPARC:#define __FLT_MIN__ 1.17549435e-38F
 // SPARC:#define __FLT_RADIX__ 2
+// SPARC:#define __INT16_MAX__ 32767
 // SPARC:#define __INT16_TYPE__ short
+// SPARC:#define __INT32_MAX__ 2147483647
 // SPARC:#define __INT32_TYPE__ int
 // SPARC:#define __INT64_C_SUFFIX__ LL
+// SPARC:#define __INT64_MAX__ 9223372036854775807LL
 // SPARC:#define __INT64_TYPE__ long long int
+// SPARC:#define __INT8_MAX__ 127
 // SPARC:#define __INT8_TYPE__ char
 // SPARC:#define __INTMAX_MAX__ 9223372036854775807LL
 // SPARC:#define __INTMAX_TYPE__ long long int
 // SPARC:#define __INTMAX_WIDTH__ 64
+// SPARC:#define __INTPTR_MAX__ 2147483647L
 // SPARC:#define __INTPTR_TYPE__ long int
 // SPARC:#define __INTPTR_WIDTH__ 32
+// SPARC:#define __INT_FAST16_MAX__ 32767
+// SPARC:#define __INT_FAST16_TYPE__ short
+// SPARC:#define __INT_FAST32_MAX__ 2147483647
+// SPARC:#define __INT_FAST32_TYPE__ int
+// SPARC:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// SPARC:#define __INT_FAST64_TYPE__ long long int
+// SPARC:#define __INT_FAST8_MAX__ 127
+// SPARC:#define __INT_FAST8_TYPE__ char
+// SPARC:#define __INT_LEAST16_MAX__ 32767
+// SPARC:#define __INT_LEAST16_TYPE__ short
+// SPARC:#define __INT_LEAST32_MAX__ 2147483647
+// SPARC:#define __INT_LEAST32_TYPE__ int
+// SPARC:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// SPARC:#define __INT_LEAST64_TYPE__ long long int
+// SPARC:#define __INT_LEAST8_MAX__ 127
+// SPARC:#define __INT_LEAST8_TYPE__ char
 // SPARC:#define __INT_MAX__ 2147483647
 // SPARC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // SPARC:#define __LDBL_DIG__ 15
@@ -3404,7 +4899,40 @@
 // SPARC:#define __SIZE_MAX__ 4294967295U
 // SPARC:#define __SIZE_TYPE__ long unsigned int
 // SPARC:#define __SIZE_WIDTH__ 32
+// SPARC:#define __UINT16_C_SUFFIX__ U
+// SPARC:#define __UINT16_MAX__ 65535U
+// SPARC:#define __UINT16_TYPE__ unsigned short
+// SPARC:#define __UINT32_C_SUFFIX__ U
+// SPARC:#define __UINT32_MAX__ 4294967295U
+// SPARC:#define __UINT32_TYPE__ unsigned int
+// SPARC:#define __UINT64_C_SUFFIX__ ULL
+// SPARC:#define __UINT64_MAX__ 18446744073709551615ULL
+// SPARC:#define __UINT64_TYPE__ long long unsigned int
+// SPARC:#define __UINT8_C_SUFFIX__ U
+// SPARC:#define __UINT8_MAX__ 255U
+// SPARC:#define __UINT8_TYPE__ unsigned char
+// SPARC:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // SPARC:#define __UINTMAX_TYPE__ long long unsigned int
+// SPARC:#define __UINTMAX_WIDTH__ 64
+// SPARC:#define __UINTPTR_MAX__ 4294967295U
+// SPARC:#define __UINTPTR_TYPE__ unsigned int
+// SPARC:#define __UINTPTR_WIDTH__ 32
+// SPARC:#define __UINT_FAST16_MAX__ 65535U
+// SPARC:#define __UINT_FAST16_TYPE__ unsigned short
+// SPARC:#define __UINT_FAST32_MAX__ 4294967295U
+// SPARC:#define __UINT_FAST32_TYPE__ unsigned int
+// SPARC:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// SPARC:#define __UINT_FAST64_TYPE__ long long unsigned int
+// SPARC:#define __UINT_FAST8_MAX__ 255U
+// SPARC:#define __UINT_FAST8_TYPE__ unsigned char
+// SPARC:#define __UINT_LEAST16_MAX__ 65535U
+// SPARC:#define __UINT_LEAST16_TYPE__ unsigned short
+// SPARC:#define __UINT_LEAST32_MAX__ 4294967295U
+// SPARC:#define __UINT_LEAST32_TYPE__ unsigned int
+// SPARC:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// SPARC:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// SPARC:#define __UINT_LEAST8_MAX__ 255U
+// SPARC:#define __UINT_LEAST8_TYPE__ unsigned char
 // SPARC:#define __USER_LABEL_PREFIX__ _
 // SPARC:#define __VERSION__ "4.2.1 Compatible
 // SPARC:#define __WCHAR_MAX__ 2147483647
@@ -3454,14 +4982,30 @@
 // TCE:#define __FLT_MIN_EXP__ (-125)
 // TCE:#define __FLT_MIN__ 1.17549435e-38F
 // TCE:#define __FLT_RADIX__ 2
+// TCE:#define __INT16_MAX__ 32767
 // TCE:#define __INT16_TYPE__ short
+// TCE:#define __INT32_MAX__ 2147483647
 // TCE:#define __INT32_TYPE__ int
+// TCE:#define __INT8_MAX__ 127
 // TCE:#define __INT8_TYPE__ char
 // TCE:#define __INTMAX_MAX__ 2147483647L
 // TCE:#define __INTMAX_TYPE__ long int
 // TCE:#define __INTMAX_WIDTH__ 32
+// TCE:#define __INTPTR_MAX__ 2147483647
 // TCE:#define __INTPTR_TYPE__ int
 // TCE:#define __INTPTR_WIDTH__ 32
+// TCE:#define __INT_FAST16_MAX__ 32767
+// TCE:#define __INT_FAST16_TYPE__ short
+// TCE:#define __INT_FAST32_MAX__ 2147483647
+// TCE:#define __INT_FAST32_TYPE__ int
+// TCE:#define __INT_FAST8_MAX__ 127
+// TCE:#define __INT_FAST8_TYPE__ char
+// TCE:#define __INT_LEAST16_MAX__ 32767
+// TCE:#define __INT_LEAST16_TYPE__ short
+// TCE:#define __INT_LEAST32_MAX__ 2147483647
+// TCE:#define __INT_LEAST32_TYPE__ int
+// TCE:#define __INT_LEAST8_MAX__ 127
+// TCE:#define __INT_LEAST8_TYPE__ char
 // TCE:#define __INT_MAX__ 2147483647
 // TCE:#define __LDBL_DENORM_MIN__ 1.40129846e-45L
 // TCE:#define __LDBL_DIG__ 6
@@ -3502,7 +5046,33 @@
 // TCE:#define __SIZE_WIDTH__ 32
 // TCE:#define __TCE_V1__ 1
 // TCE:#define __TCE__ 1
+// TCE:#define __UINT16_C_SUFFIX__ U
+// TCE:#define __UINT16_MAX__ 65535U
+// TCE:#define __UINT16_TYPE__ unsigned short
+// TCE:#define __UINT32_C_SUFFIX__ U
+// TCE:#define __UINT32_MAX__ 4294967295U
+// TCE:#define __UINT32_TYPE__ unsigned int
+// TCE:#define __UINT8_C_SUFFIX__ U
+// TCE:#define __UINT8_MAX__ 255U
+// TCE:#define __UINT8_TYPE__ unsigned char
+// TCE:#define __UINTMAX_MAX__ 4294967295UL
 // TCE:#define __UINTMAX_TYPE__ long unsigned int
+// TCE:#define __UINTMAX_WIDTH__ 32
+// TCE:#define __UINTPTR_MAX__ 4294967295U
+// TCE:#define __UINTPTR_TYPE__ unsigned int
+// TCE:#define __UINTPTR_WIDTH__ 32
+// TCE:#define __UINT_FAST16_MAX__ 65535U
+// TCE:#define __UINT_FAST16_TYPE__ unsigned short
+// TCE:#define __UINT_FAST32_MAX__ 4294967295U
+// TCE:#define __UINT_FAST32_TYPE__ unsigned int
+// TCE:#define __UINT_FAST8_MAX__ 255U
+// TCE:#define __UINT_FAST8_TYPE__ unsigned char
+// TCE:#define __UINT_LEAST16_MAX__ 65535U
+// TCE:#define __UINT_LEAST16_TYPE__ unsigned short
+// TCE:#define __UINT_LEAST32_MAX__ 4294967295U
+// TCE:#define __UINT_LEAST32_TYPE__ unsigned int
+// TCE:#define __UINT_LEAST8_MAX__ 255U
+// TCE:#define __UINT_LEAST8_TYPE__ unsigned char
 // TCE:#define __USER_LABEL_PREFIX__ _
 // TCE:#define __WCHAR_MAX__ 2147483647
 // TCE:#define __WCHAR_TYPE__ int
@@ -3549,16 +5119,37 @@
 // X86_64:#define __FLT_MIN_EXP__ (-125)
 // X86_64:#define __FLT_MIN__ 1.17549435e-38F
 // X86_64:#define __FLT_RADIX__ 2
+// X86_64:#define __INT16_MAX__ 32767
 // X86_64:#define __INT16_TYPE__ short
+// X86_64:#define __INT32_MAX__ 2147483647
 // X86_64:#define __INT32_TYPE__ int
 // X86_64:#define __INT64_C_SUFFIX__ L
+// X86_64:#define __INT64_MAX__ 9223372036854775807L
 // X86_64:#define __INT64_TYPE__ long int
+// X86_64:#define __INT8_MAX__ 127
 // X86_64:#define __INT8_TYPE__ char
 // X86_64:#define __INTMAX_MAX__ 9223372036854775807L
 // X86_64:#define __INTMAX_TYPE__ long int
 // X86_64:#define __INTMAX_WIDTH__ 64
+// X86_64:#define __INTPTR_MAX__ 9223372036854775807L
 // X86_64:#define __INTPTR_TYPE__ long int
 // X86_64:#define __INTPTR_WIDTH__ 64
+// X86_64:#define __INT_FAST16_MAX__ 32767
+// X86_64:#define __INT_FAST16_TYPE__ short
+// X86_64:#define __INT_FAST32_MAX__ 2147483647
+// X86_64:#define __INT_FAST32_TYPE__ int
+// X86_64:#define __INT_FAST64_MAX__ 9223372036854775807L
+// X86_64:#define __INT_FAST64_TYPE__ long int
+// X86_64:#define __INT_FAST8_MAX__ 127
+// X86_64:#define __INT_FAST8_TYPE__ char
+// X86_64:#define __INT_LEAST16_MAX__ 32767
+// X86_64:#define __INT_LEAST16_TYPE__ short
+// X86_64:#define __INT_LEAST32_MAX__ 2147483647
+// X86_64:#define __INT_LEAST32_TYPE__ int
+// X86_64:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// X86_64:#define __INT_LEAST64_TYPE__ long int
+// X86_64:#define __INT_LEAST8_MAX__ 127
+// X86_64:#define __INT_LEAST8_TYPE__ char
 // X86_64:#define __INT_MAX__ 2147483647
 // X86_64:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // X86_64:#define __LDBL_DIG__ 18
@@ -3605,7 +5196,40 @@
 // X86_64:#define __SSE2__ 1
 // X86_64:#define __SSE_MATH__ 1
 // X86_64:#define __SSE__ 1
+// X86_64:#define __UINT16_C_SUFFIX__ U
+// X86_64:#define __UINT16_MAX__ 65535U
+// X86_64:#define __UINT16_TYPE__ unsigned short
+// X86_64:#define __UINT32_C_SUFFIX__ U
+// X86_64:#define __UINT32_MAX__ 4294967295U
+// X86_64:#define __UINT32_TYPE__ unsigned int
+// X86_64:#define __UINT64_C_SUFFIX__ UL
+// X86_64:#define __UINT64_MAX__ 18446744073709551615UL
+// X86_64:#define __UINT64_TYPE__ long unsigned int
+// X86_64:#define __UINT8_C_SUFFIX__ U
+// X86_64:#define __UINT8_MAX__ 255U
+// X86_64:#define __UINT8_TYPE__ unsigned char
+// X86_64:#define __UINTMAX_MAX__ 18446744073709551615UL
 // X86_64:#define __UINTMAX_TYPE__ long unsigned int
+// X86_64:#define __UINTMAX_WIDTH__ 64
+// X86_64:#define __UINTPTR_MAX__ 18446744073709551615UL
+// X86_64:#define __UINTPTR_TYPE__ long unsigned int
+// X86_64:#define __UINTPTR_WIDTH__ 64
+// X86_64:#define __UINT_FAST16_MAX__ 65535U
+// X86_64:#define __UINT_FAST16_TYPE__ unsigned short
+// X86_64:#define __UINT_FAST32_MAX__ 4294967295U
+// X86_64:#define __UINT_FAST32_TYPE__ unsigned int
+// X86_64:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// X86_64:#define __UINT_FAST64_TYPE__ long unsigned int
+// X86_64:#define __UINT_FAST8_MAX__ 255U
+// X86_64:#define __UINT_FAST8_TYPE__ unsigned char
+// X86_64:#define __UINT_LEAST16_MAX__ 65535U
+// X86_64:#define __UINT_LEAST16_TYPE__ unsigned short
+// X86_64:#define __UINT_LEAST32_MAX__ 4294967295U
+// X86_64:#define __UINT_LEAST32_TYPE__ unsigned int
+// X86_64:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// X86_64:#define __UINT_LEAST64_TYPE__ long unsigned int
+// X86_64:#define __UINT_LEAST8_MAX__ 255U
+// X86_64:#define __UINT_LEAST8_TYPE__ unsigned char
 // X86_64:#define __USER_LABEL_PREFIX__ _
 // X86_64:#define __WCHAR_MAX__ 2147483647
 // X86_64:#define __WCHAR_TYPE__ int
@@ -3653,16 +5277,37 @@
 // X86_64-LINUX:#define __FLT_MIN_EXP__ (-125)
 // X86_64-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // X86_64-LINUX:#define __FLT_RADIX__ 2
+// X86_64-LINUX:#define __INT16_MAX__ 32767
 // X86_64-LINUX:#define __INT16_TYPE__ short
+// X86_64-LINUX:#define __INT32_MAX__ 2147483647
 // X86_64-LINUX:#define __INT32_TYPE__ int
 // X86_64-LINUX:#define __INT64_C_SUFFIX__ L
+// X86_64-LINUX:#define __INT64_MAX__ 9223372036854775807L
 // X86_64-LINUX:#define __INT64_TYPE__ long int
+// X86_64-LINUX:#define __INT8_MAX__ 127
 // X86_64-LINUX:#define __INT8_TYPE__ char
 // X86_64-LINUX:#define __INTMAX_MAX__ 9223372036854775807L
 // X86_64-LINUX:#define __INTMAX_TYPE__ long int
 // X86_64-LINUX:#define __INTMAX_WIDTH__ 64
+// X86_64-LINUX:#define __INTPTR_MAX__ 9223372036854775807L
 // X86_64-LINUX:#define __INTPTR_TYPE__ long int
 // X86_64-LINUX:#define __INTPTR_WIDTH__ 64
+// X86_64-LINUX:#define __INT_FAST16_MAX__ 32767
+// X86_64-LINUX:#define __INT_FAST16_TYPE__ short
+// X86_64-LINUX:#define __INT_FAST32_MAX__ 2147483647
+// X86_64-LINUX:#define __INT_FAST32_TYPE__ int
+// X86_64-LINUX:#define __INT_FAST64_MAX__ 9223372036854775807L
+// X86_64-LINUX:#define __INT_FAST64_TYPE__ long int
+// X86_64-LINUX:#define __INT_FAST8_MAX__ 127
+// X86_64-LINUX:#define __INT_FAST8_TYPE__ char
+// X86_64-LINUX:#define __INT_LEAST16_MAX__ 32767
+// X86_64-LINUX:#define __INT_LEAST16_TYPE__ short
+// X86_64-LINUX:#define __INT_LEAST32_MAX__ 2147483647
+// X86_64-LINUX:#define __INT_LEAST32_TYPE__ int
+// X86_64-LINUX:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// X86_64-LINUX:#define __INT_LEAST64_TYPE__ long int
+// X86_64-LINUX:#define __INT_LEAST8_MAX__ 127
+// X86_64-LINUX:#define __INT_LEAST8_TYPE__ char
 // X86_64-LINUX:#define __INT_MAX__ 2147483647
 // X86_64-LINUX:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // X86_64-LINUX:#define __LDBL_DIG__ 18
@@ -3709,7 +5354,40 @@
 // X86_64-LINUX:#define __SSE2__ 1
 // X86_64-LINUX:#define __SSE_MATH__ 1
 // X86_64-LINUX:#define __SSE__ 1
+// X86_64-LINUX:#define __UINT16_C_SUFFIX__ U
+// X86_64-LINUX:#define __UINT16_MAX__ 65535U
+// X86_64-LINUX:#define __UINT16_TYPE__ unsigned short
+// X86_64-LINUX:#define __UINT32_C_SUFFIX__ U
+// X86_64-LINUX:#define __UINT32_MAX__ 4294967295U
+// X86_64-LINUX:#define __UINT32_TYPE__ unsigned int
+// X86_64-LINUX:#define __UINT64_C_SUFFIX__ UL
+// X86_64-LINUX:#define __UINT64_MAX__ 18446744073709551615UL
+// X86_64-LINUX:#define __UINT64_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINT8_C_SUFFIX__ U
+// X86_64-LINUX:#define __UINT8_MAX__ 255U
+// X86_64-LINUX:#define __UINT8_TYPE__ unsigned char
+// X86_64-LINUX:#define __UINTMAX_MAX__ 18446744073709551615UL
 // X86_64-LINUX:#define __UINTMAX_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINTMAX_WIDTH__ 64
+// X86_64-LINUX:#define __UINTPTR_MAX__ 18446744073709551615UL
+// X86_64-LINUX:#define __UINTPTR_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINTPTR_WIDTH__ 64
+// X86_64-LINUX:#define __UINT_FAST16_MAX__ 65535U
+// X86_64-LINUX:#define __UINT_FAST16_TYPE__ unsigned short
+// X86_64-LINUX:#define __UINT_FAST32_MAX__ 4294967295U
+// X86_64-LINUX:#define __UINT_FAST32_TYPE__ unsigned int
+// X86_64-LINUX:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// X86_64-LINUX:#define __UINT_FAST64_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINT_FAST8_MAX__ 255U
+// X86_64-LINUX:#define __UINT_FAST8_TYPE__ unsigned char
+// X86_64-LINUX:#define __UINT_LEAST16_MAX__ 65535U
+// X86_64-LINUX:#define __UINT_LEAST16_TYPE__ unsigned short
+// X86_64-LINUX:#define __UINT_LEAST32_MAX__ 4294967295U
+// X86_64-LINUX:#define __UINT_LEAST32_TYPE__ unsigned int
+// X86_64-LINUX:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// X86_64-LINUX:#define __UINT_LEAST64_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINT_LEAST8_MAX__ 255U
+// X86_64-LINUX:#define __UINT_LEAST8_TYPE__ unsigned char
 // X86_64-LINUX:#define __USER_LABEL_PREFIX__
 // X86_64-LINUX:#define __WCHAR_MAX__ 2147483647
 // X86_64-LINUX:#define __WCHAR_TYPE__ int
@@ -3763,16 +5441,37 @@
 // X86_64-NETBSD:#define __FLT_MIN_EXP__ (-125)
 // X86_64-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
 // X86_64-NETBSD:#define __FLT_RADIX__ 2
+// X86_64-NETBSD:#define __INT16_MAX__ 32767
 // X86_64-NETBSD:#define __INT16_TYPE__ short
+// X86_64-NETBSD:#define __INT32_MAX__ 2147483647
 // X86_64-NETBSD:#define __INT32_TYPE__ int
 // X86_64-NETBSD:#define __INT64_C_SUFFIX__ L
+// X86_64-NETBSD:#define __INT64_MAX__ 9223372036854775807L
 // X86_64-NETBSD:#define __INT64_TYPE__ long int
+// X86_64-NETBSD:#define __INT8_MAX__ 127
 // X86_64-NETBSD:#define __INT8_TYPE__ char
 // X86_64-NETBSD:#define __INTMAX_MAX__ 9223372036854775807L
 // X86_64-NETBSD:#define __INTMAX_TYPE__ long int
 // X86_64-NETBSD:#define __INTMAX_WIDTH__ 64
+// X86_64-NETBSD:#define __INTPTR_MAX__ 9223372036854775807L
 // X86_64-NETBSD:#define __INTPTR_TYPE__ long int
 // X86_64-NETBSD:#define __INTPTR_WIDTH__ 64
+// X86_64-NETBSD:#define __INT_FAST16_MAX__ 32767
+// X86_64-NETBSD:#define __INT_FAST16_TYPE__ short
+// X86_64-NETBSD:#define __INT_FAST32_MAX__ 2147483647
+// X86_64-NETBSD:#define __INT_FAST32_TYPE__ int
+// X86_64-NETBSD:#define __INT_FAST64_MAX__ 9223372036854775807L
+// X86_64-NETBSD:#define __INT_FAST64_TYPE__ long int
+// X86_64-NETBSD:#define __INT_FAST8_MAX__ 127
+// X86_64-NETBSD:#define __INT_FAST8_TYPE__ char
+// X86_64-NETBSD:#define __INT_LEAST16_MAX__ 32767
+// X86_64-NETBSD:#define __INT_LEAST16_TYPE__ short
+// X86_64-NETBSD:#define __INT_LEAST32_MAX__ 2147483647
+// X86_64-NETBSD:#define __INT_LEAST32_TYPE__ int
+// X86_64-NETBSD:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// X86_64-NETBSD:#define __INT_LEAST64_TYPE__ long int
+// X86_64-NETBSD:#define __INT_LEAST8_MAX__ 127
+// X86_64-NETBSD:#define __INT_LEAST8_TYPE__ char
 // X86_64-NETBSD:#define __INT_MAX__ 2147483647
 // X86_64-NETBSD:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // X86_64-NETBSD:#define __LDBL_DIG__ 18
@@ -3819,7 +5518,40 @@
 // X86_64-NETBSD:#define __SSE2__ 1
 // X86_64-NETBSD:#define __SSE_MATH__ 1
 // X86_64-NETBSD:#define __SSE__ 1
+// X86_64-NETBSD:#define __UINT16_C_SUFFIX__ U
+// X86_64-NETBSD:#define __UINT16_MAX__ 65535U
+// X86_64-NETBSD:#define __UINT16_TYPE__ unsigned short
+// X86_64-NETBSD:#define __UINT32_C_SUFFIX__ U
+// X86_64-NETBSD:#define __UINT32_MAX__ 4294967295U
+// X86_64-NETBSD:#define __UINT32_TYPE__ unsigned int
+// X86_64-NETBSD:#define __UINT64_C_SUFFIX__ UL
+// X86_64-NETBSD:#define __UINT64_MAX__ 18446744073709551615UL
+// X86_64-NETBSD:#define __UINT64_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINT8_C_SUFFIX__ U
+// X86_64-NETBSD:#define __UINT8_MAX__ 255U
+// X86_64-NETBSD:#define __UINT8_TYPE__ unsigned char
+// X86_64-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615UL
 // X86_64-NETBSD:#define __UINTMAX_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINTMAX_WIDTH__ 64
+// X86_64-NETBSD:#define __UINTPTR_MAX__ 18446744073709551615UL
+// X86_64-NETBSD:#define __UINTPTR_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINTPTR_WIDTH__ 64
+// X86_64-NETBSD:#define __UINT_FAST16_MAX__ 65535U
+// X86_64-NETBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// X86_64-NETBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// X86_64-NETBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// X86_64-NETBSD:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// X86_64-NETBSD:#define __UINT_FAST64_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINT_FAST8_MAX__ 255U
+// X86_64-NETBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// X86_64-NETBSD:#define __UINT_LEAST16_MAX__ 65535U
+// X86_64-NETBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// X86_64-NETBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// X86_64-NETBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// X86_64-NETBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// X86_64-NETBSD:#define __UINT_LEAST64_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINT_LEAST8_MAX__ 255U
+// X86_64-NETBSD:#define __UINT_LEAST8_TYPE__ unsigned char
 // X86_64-NETBSD:#define __USER_LABEL_PREFIX__
 // X86_64-NETBSD:#define __WCHAR_MAX__ 2147483647
 // X86_64-NETBSD:#define __WCHAR_TYPE__ int
diff --git a/test/Preprocessor/macho-embedded-predefines.c b/test/Preprocessor/macho-embedded-predefines.c
index 8356bc9..74f2919 100644
--- a/test/Preprocessor/macho-embedded-predefines.c
+++ b/test/Preprocessor/macho-embedded-predefines.c
@@ -1,5 +1,20 @@
-// RUN: %clang_cc1 -E -dM -triple thumbv7m-apple-unknown-macho %s | FileCheck %s
+// RUN: %clang_cc1 -E -dM -triple thumbv7m-apple-unknown-macho -target-cpu cortex-m3 %s | FileCheck %s -check-prefix CHECK-7M
 
-// CHECK: #define __APPLE_CC__
-// CHECK: #define __APPLE__
-// CHECK-NOT: #define __MACH__
+// CHECK-7M: #define __APPLE_CC__
+// CHECK-7M: #define __APPLE__
+// CHECK-7M: #define __ARM_ARCH_7M__
+// CHECK-7M-NOT: #define __MACH__
+
+// RUN: %clang_cc1 -E -dM -triple thumbv7em-apple-unknown-macho -target-cpu cortex-m4 %s | FileCheck %s -check-prefix CHECK-7EM
+
+// CHECK-7EM: #define __APPLE_CC__
+// CHECK-7EM: #define __APPLE__
+// CHECK-7EM: #define __ARM_ARCH_7EM__
+// CHECK-7EM-NOT: #define __MACH__
+
+// RUN: %clang_cc1 -E -dM -triple thumbv6m-apple-unknown-macho -target-cpu cortex-m0 %s | FileCheck %s -check-prefix CHECK-6M
+
+// CHECK-6M: #define __APPLE_CC__
+// CHECK-6M: #define __APPLE__
+// CHECK-6M: #define __ARM_ARCH_6M__
+// CHECK-6M-NOT: #define __MACH__
diff --git a/test/Preprocessor/predefined-macros.c b/test/Preprocessor/predefined-macros.c
index 11449f9..3e0b8a0 100644
--- a/test/Preprocessor/predefined-macros.c
+++ b/test/Preprocessor/predefined-macros.c
@@ -9,6 +9,63 @@
 // CHECK-MS: #define _M_IX86_FP
 // CHECK-MS: #define _WIN32 1
 // CHECK-MS-NOT: #define __GNUC__
+// CHECK-MS-NOT: #define __STRICT_ANSI__
+//
+// RUN: %clang_cc1 %s -E -dM -triple i686-pc-win32 -fms-compatibility \
+// RUN:     -o - | FileCheck %s --check-prefix=CHECK-MS-STDINT
+// CHECK-MS-STDINT-NOT:#define __INT16_MAX__ 32767
+// CHECK-MS-STDINT-NOT:#define __INT32_MAX__ 2147483647
+// CHECK-MS-STDINT-NOT:#define __INT64_MAX__ 9223372036854775807LL
+// CHECK-MS-STDINT-NOT:#define __INT8_MAX__ 127
+// CHECK-MS-STDINT-NOT:#define __INTPTR_MAX__ 2147483647
+// CHECK-MS-STDINT-NOT:#define __INT_FAST16_MAX__ 32767
+// CHECK-MS-STDINT-NOT:#define __INT_FAST16_TYPE__ short
+// CHECK-MS-STDINT-NOT:#define __INT_FAST32_MAX__ 2147483647
+// CHECK-MS-STDINT-NOT:#define __INT_FAST32_TYPE__ int
+// CHECK-MS-STDINT-NOT:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// CHECK-MS-STDINT-NOT:#define __INT_FAST64_TYPE__ long long int
+// CHECK-MS-STDINT-NOT:#define __INT_FAST8_MAX__ 127
+// CHECK-MS-STDINT-NOT:#define __INT_FAST8_TYPE__ char
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST16_MAX__ 32767
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST16_TYPE__ short
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST32_MAX__ 2147483647
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST32_TYPE__ int
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST64_TYPE__ long long int
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST8_MAX__ 127
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST8_TYPE__ char
+// CHECK-MS-STDINT-NOT:#define __UINT16_C_SUFFIX__ U
+// CHECK-MS-STDINT-NOT:#define __UINT16_MAX__ 65535U
+// CHECK-MS-STDINT-NOT:#define __UINT16_TYPE__ unsigned short
+// CHECK-MS-STDINT-NOT:#define __UINT32_C_SUFFIX__ U
+// CHECK-MS-STDINT-NOT:#define __UINT32_MAX__ 4294967295U
+// CHECK-MS-STDINT-NOT:#define __UINT32_TYPE__ unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT64_C_SUFFIX__ ULL
+// CHECK-MS-STDINT-NOT:#define __UINT64_MAX__ 18446744073709551615ULL
+// CHECK-MS-STDINT-NOT:#define __UINT64_TYPE__ long long unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT8_C_SUFFIX__ U
+// CHECK-MS-STDINT-NOT:#define __UINT8_MAX__ 255U
+// CHECK-MS-STDINT-NOT:#define __UINT8_TYPE__ unsigned char
+// CHECK-MS-STDINT-NOT:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// CHECK-MS-STDINT-NOT:#define __UINTPTR_MAX__ 4294967295U
+// CHECK-MS-STDINT-NOT:#define __UINTPTR_TYPE__ unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINTPTR_WIDTH__ 32
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST16_MAX__ 65535U
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST16_TYPE__ unsigned short
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST32_MAX__ 4294967295U
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST32_TYPE__ unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST64_TYPE__ long long unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST8_MAX__ 255U
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST8_TYPE__ unsigned char
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST16_MAX__ 65535U
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST16_TYPE__ unsigned short
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST32_MAX__ 4294967295U
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST32_TYPE__ unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST8_MAX__ 255U
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST8_TYPE__ unsigned char
 //
 // RUN: %clang_cc1 %s -E -dM -ffast-math -o - \
 // RUN:   | FileCheck %s --check-prefix=CHECK-FAST-MATH
diff --git a/test/Profile/Inputs/c-unprofiled.proftext b/test/Profile/Inputs/c-unprofiled.proftext
new file mode 100644
index 0000000..d2ef7ae
--- /dev/null
+++ b/test/Profile/Inputs/c-unprofiled.proftext
@@ -0,0 +1,10 @@
+function_in_header
+10
+2
+1
+0
+
+main
+0
+1
+1
diff --git a/test/Profile/Inputs/profiled_header.h b/test/Profile/Inputs/profiled_header.h
new file mode 100644
index 0000000..fa649d4
--- /dev/null
+++ b/test/Profile/Inputs/profiled_header.h
@@ -0,0 +1,3 @@
+void function_in_header(int i) {
+  if (i) {}
+}
diff --git a/test/Profile/c-unprofiled.c b/test/Profile/c-unprofiled.c
new file mode 100644
index 0000000..275cd2d
--- /dev/null
+++ b/test/Profile/c-unprofiled.c
@@ -0,0 +1,26 @@
+// Test that unprofiled files are recognized. Here, we have two functions in the
+// profile, main() and function_in_header, but we use the profile on a file that
+// has the profile-less some_unprofiled_function so that the only profiled code
+// in #included in a header.
+
+// FIXME: It would be nice to use -verify here instead of FileCheck, but -verify
+// doesn't play well with warnings that have no line number.
+
+// RUN: llvm-profdata merge %S/Inputs/c-unprofiled.proftext -o %t.profdata
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-unprofiled.c -I %S/Inputs/ %s -o /dev/null -emit-llvm -fprofile-instr-use=%t.profdata -Wprofile-instr-unprofiled 2>&1 | FileCheck %s
+
+// CHECK: warning: no profile data available for file "c-unprofiled.c"
+
+#include "profiled_header.h"
+
+#ifdef GENERATE_OUTDATED_DATA
+int main(int argc, const char *argv[]) {
+  function_in_header(0);
+  return 0;
+}
+#else
+void some_unprofiled_function(int i) {
+  if (i)
+    function_in_header(i);
+}
+#endif
diff --git a/test/Sema/__try.c b/test/Sema/__try.c
index 1641402..a355de9 100644
--- a/test/Sema/__try.c
+++ b/test/Sema/__try.c
@@ -170,3 +170,22 @@
   (void)GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}}
   (void)AbnormalTermination();  // expected-error{{only allowed in __finally block}}
 }
+
+void test_seh_leave_stmt() {
+  __leave; // expected-error{{'__leave' statement not in __try block}}
+
+  __try {
+    __leave;
+    __leave 4; // expected-error{{expected ';' after __leave statement}}
+  } __except(1) {
+    __leave; // expected-error{{'__leave' statement not in __try block}}
+  }
+
+  __try {
+    __leave;
+  } __finally {
+    __leave; // expected-error{{'__leave' statement not in __try block}}
+  }
+  __leave; // expected-error{{'__leave' statement not in __try block}}
+}
+
diff --git a/test/Sema/align-x86.c b/test/Sema/align-x86.c
index 6b93a48..f112c63 100644
--- a/test/Sema/align-x86.c
+++ b/test/Sema/align-x86.c
@@ -23,6 +23,10 @@
 short chk1[__alignof__(g4) == 1 ? 1 : -1];
 short chk2[__alignof__(g4.a) == 1 ? 1 : -1];
 
+double g6[3];
+short chk1[__alignof__(g6) == 8 ? 1 : -1];
+short chk2[__alignof__(double[3]) == 8 ? 1 : -1];
+
 
 // PR5637
 
diff --git a/test/Sema/arm-neon-types.c b/test/Sema/arm-neon-types.c
index a49de12..a5ee708 100644
--- a/test/Sema/arm-neon-types.c
+++ b/test/Sema/arm-neon-types.c
@@ -17,7 +17,7 @@
 float32x2_t test3(uint32x2_t x) {
   // FIXME: The "incompatible result type" error is due to pr10112 and should be
   // removed when that is fixed.
-  return vcvt_n_f32_u32(x, 0); // expected-error {{argument should be a value from 1 to 32}} expected-error {{incompatible result type}}
+  return vcvt_n_f32_u32(x, 0); // expected-error {{argument should be a value from 1 to 32}}
 }
 
 typedef signed int vSInt32 __attribute__((__vector_size__(16)));
diff --git a/test/Sema/arm64-neon-args.c b/test/Sema/arm64-neon-args.c
index 9bd103a..315a704 100644
--- a/test/Sema/arm64-neon-args.c
+++ b/test/Sema/arm64-neon-args.c
@@ -5,7 +5,7 @@
 
 // rdar://13527900
 void vcopy_reject(float32x4_t vOut0, float32x4_t vAlpha, int t) {
-  vcopyq_laneq_f32(vOut0, 1, vAlpha, t); // expected-error {{argument to '__builtin_neon_vgetq_lane_f32' must be a constant integer}} expected-error {{initializing 'float32_t' (aka 'float') with an expression of incompatible type 'void'}}
+  vcopyq_laneq_f32(vOut0, 1, vAlpha, t); // expected-error {{argument to '__builtin_neon_vgetq_lane_f32' must be a constant integer}}
 }
 
 // rdar://problem/15256199
diff --git a/test/Sema/arm_acle.c b/test/Sema/arm_acle.c
new file mode 100644
index 0000000..9a70f85
--- /dev/null
+++ b/test/Sema/arm_acle.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple armv8 -target-cpu cortex-a57 -fsyntax-only -ffreestanding -verify %s
+
+#include <arm_acle.h>
+
+/*
+ * Saturating intrinsics
+ * Second argument for SSAT and USAT intrinsics must be compile-time constant,
+ * otherwise an error should be raised.
+ */
+int32_t test_ssat_const_diag(int32_t t, const int32_t v) {
+  return __ssat(t, v);  // expected-error-re {{argument to {{.*}} must be a constant integer}}
+}
+
+int32_t test_usat_const_diag(int32_t t, const int32_t v) {
+  return __usat(t, v);  // expected-error-re {{argument to {{.*}} must be a constant integer}}
+}
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index 4d84afc..22b7497 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 %s -Wno-private-extern -triple i386-pc-linux-gnu -verify -fsyntax-only
 
+
+
 void f() {
   int i;
 
@@ -147,3 +149,11 @@
   __asm("0.0":"=g"(ret)); // no-error
   return ret;
 }
+
+// PR19837
+struct foo {
+  int a;
+  char b;
+};
+register struct foo bar asm("sp"); // expected-error {{bad type for named register variable}}
+register float baz asm("sp"); // expected-error {{bad type for named register variable}}
diff --git a/test/Sema/attr-alias-cycle.c b/test/Sema/attr-alias-cycle.c
deleted file mode 100644
index ce024c3..0000000
--- a/test/Sema/attr-alias-cycle.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux  -fsyntax-only -verify -emit-llvm-only %s
-
-// FIXME: The attributes use mangled names. Since we only keep a mapping from
-// mangled name to llvm GlobalValue, we don't see the clang level decl for
-// an alias target when constructing the alias. Given that and that alias cycles
-// are not representable in LLVM, we only note the issues when the cycle is
-// first formed.
-
-// FIXME: This error is detected early in CodeGen. Once the first error is
-// found, Diags.hasErrorOccurred() returs true and we stop the codegen of the
-// file. The consequence is that we don't find any subsequent error.
-
-void f1() __attribute__((alias("g1")));
-void g1() __attribute__((alias("f1"))); // expected-error {{alias definition is part of a cycle}}
-
-void h1() __attribute__((alias("g1")));
diff --git a/test/Sema/attr-alias-elf.c b/test/Sema/attr-alias-elf.c
index 82ab076..f14514d 100644
--- a/test/Sema/attr-alias-elf.c
+++ b/test/Sema/attr-alias-elf.c
@@ -35,6 +35,13 @@
 void f9() __attribute__((alias("g9")));
 void g9() {}
 
+void f10() __attribute__((alias("g10"))); // expected-error {{alias definition is part of a cycle}}
+void g10() __attribute__((alias("f10"))); // expected-error {{alias definition is part of a cycle}}
+
+// FIXME: This could be a bit better, h10 is not part of the cycle, it points
+// to it.
+void h10() __attribute__((alias("g10"))); // expected-error {{alias definition is part of a cycle}}
+
 extern int a1 __attribute__((alias("b1")));
 int b1 = 42;
 
@@ -57,3 +64,6 @@
 __attribute__((section("test"))) void test4_bar() { }
 void test4_foo() __attribute__((section("test")));
 void test4_foo() __attribute__((alias("test4_bar")));
+
+int test5_bar = 0;
+extern struct incomplete_type test5_foo __attribute__((alias("test5_bar")));
diff --git a/test/Sema/big-endian-neon-initializers.c b/test/Sema/big-endian-neon-initializers.c
new file mode 100644
index 0000000..ffe3109
--- /dev/null
+++ b/test/Sema/big-endian-neon-initializers.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -triple arm64_be -target-feature +neon -verify -fsyntax-only -ffreestanding
+// RUN: %clang_cc1 %s -triple armebv7 -target-cpu cortex-a8 -verify -fsyntax-only -ffreestanding
+
+#include <arm_neon.h>
+
+int32x4_t x = {1, 2, 3, 4}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1q_s32() to initialize a vector from memory, or vcombine_s32(vcreate_s32(), vcreate_s32()) to initialize from integer constants}}
+int16x4_t y = {1, 2, 3, 4}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1_s16() to initialize a vector from memory, or vcreate_s16() to initialize from an integer constant}}
+int64x2_t z = {1, 2}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1q_s64() to initialize a vector from memory, or vcombine_s64(vcreate_s64(), vcreate_s64()) to initialize from integer constants}}
+float32x2_t b = {1, 2}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1_f32() to initialize a vector from memory, or vcreate_f32() to initialize from an integer constant}}
+
+// No warning expected here.
+typedef int v4si __attribute__ ((vector_size (16)));
+v4si c = {1, 2, 3, 4};
diff --git a/test/Sema/builtins-arm-exclusive.c b/test/Sema/builtins-arm-exclusive.c
index 8c78403..4e6a96b 100644
--- a/test/Sema/builtins-arm-exclusive.c
+++ b/test/Sema/builtins-arm-exclusive.c
@@ -55,6 +55,57 @@
   return res;
 }
 
+int test_ldaex(char *addr) {
+  int sum = 0;
+  sum += __builtin_arm_ldaex(addr);
+  sum += __builtin_arm_ldaex((short *)addr);
+  sum += __builtin_arm_ldaex((int *)addr);
+  sum += __builtin_arm_ldaex((long long *)addr);
+  sum += __builtin_arm_ldaex((float *)addr);
+  sum += __builtin_arm_ldaex((double *)addr);
+  sum += *__builtin_arm_ldaex((int **)addr);
+  sum += __builtin_arm_ldaex((struct Simple **)addr)->a;
+  sum += __builtin_arm_ldaex((volatile char *)addr);
+  sum += __builtin_arm_ldaex((const volatile char *)addr);
+
+  // In principle this might be valid, but stick to ints and floats for scalar
+  // types at the moment.
+  sum += __builtin_arm_ldaex((struct Simple *)addr).a; // expected-error {{address argument to atomic builtin must be a pointer to}}
+
+  sum += __builtin_arm_ldaex((__int128 *)addr); // expected-error {{__int128 is not supported on this target}} expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type}}
+
+  __builtin_arm_ldaex(); // expected-error {{too few arguments to function call}}
+  __builtin_arm_ldaex(1, 2); // expected-error {{too many arguments to function call}}
+  return sum;
+}
+
+int test_stlex(char *addr) {
+  int res = 0;
+  struct Simple var = {0};
+  res |= __builtin_arm_stlex(4, addr);
+  res |= __builtin_arm_stlex(42, (short *)addr);
+  res |= __builtin_arm_stlex(42, (int *)addr);
+  res |= __builtin_arm_stlex(42, (long long *)addr);
+  res |= __builtin_arm_stlex(2.71828f, (float *)addr);
+  res |= __builtin_arm_stlex(3.14159, (double *)addr);
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr);
+
+  res |= __builtin_arm_stlex(42, (volatile char *)addr);
+  res |= __builtin_arm_stlex(42, (char *const)addr);
+  res |= __builtin_arm_stlex(42, (const char *)addr); // expected-warning {{passing 'const char *' to parameter of type 'volatile char *' discards qualifiers}}
+
+
+  res |= __builtin_arm_stlex(var, (struct Simple *)addr); // expected-error {{address argument to atomic builtin must be a pointer to}}
+  res |= __builtin_arm_stlex(var, (struct Simple **)addr); // expected-error {{passing 'struct Simple' to parameter of incompatible type 'struct Simple *'}}
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr).a; // expected-error {{is not a structure or union}}
+
+  res |= __builtin_arm_stlex(1, (__int128 *)addr); // expected-error {{__int128 is not supported on this target}} expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type}}
+
+  __builtin_arm_stlex(1); // expected-error {{too few arguments to function call}}
+  __builtin_arm_stlex(1, 2, 3); // expected-error {{too many arguments to function call}}
+  return res;
+}
+
 void test_clrex() {
   __builtin_arm_clrex();
   __builtin_arm_clrex(1); // expected-error {{too many arguments to function call}}
diff --git a/test/Sema/builtins-arm.c b/test/Sema/builtins-arm.c
index 3ac1da0..6c367d3 100644
--- a/test/Sema/builtins-arm.c
+++ b/test/Sema/builtins-arm.c
@@ -31,4 +31,10 @@
   *ptr = '0'; // expected-error {{incomplete type 'void' is not assignable}}
 }
 
+void test3() {
+  __builtin_arm_dsb(16); // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_arm_dmb(17); // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_arm_isb(18); // expected-error {{argument should be a value from 0 to 15}}
+}
+
 #endif
diff --git a/test/Sema/builtins-arm64-exclusive.c b/test/Sema/builtins-arm64-exclusive.c
index 0be9c17..4d678cc 100644
--- a/test/Sema/builtins-arm64-exclusive.c
+++ b/test/Sema/builtins-arm64-exclusive.c
@@ -53,6 +53,55 @@
   return res;
 }
 
+int test_ldaex(char *addr) {
+  int sum = 0;
+  sum += __builtin_arm_ldaex(addr);
+  sum += __builtin_arm_ldaex((short *)addr);
+  sum += __builtin_arm_ldaex((int *)addr);
+  sum += __builtin_arm_ldaex((long long *)addr);
+  sum += __builtin_arm_ldaex((__int128 *)addr);
+  sum += __builtin_arm_ldaex((float *)addr);
+  sum += __builtin_arm_ldaex((double *)addr);
+  sum += *__builtin_arm_ldaex((int **)addr);
+  sum += __builtin_arm_ldaex((struct Simple **)addr)->a;
+  sum += __builtin_arm_ldaex((volatile char *)addr);
+  sum += __builtin_arm_ldaex((const volatile char *)addr);
+
+  // In principle this might be valid, but stick to ints and floats for scalar
+  // types at the moment.
+  sum += __builtin_arm_ldaex((struct Simple *)addr).a; // expected-error {{address argument to atomic builtin must be a pointer to}}
+
+  __builtin_arm_ldaex(); // expected-error {{too few arguments to function call}}
+  __builtin_arm_ldaex(1, 2); // expected-error {{too many arguments to function call}}
+  return sum;
+}
+
+int test_stlex(char *addr) {
+  int res = 0;
+  struct Simple var = {0};
+  res |= __builtin_arm_stlex(4, addr);
+  res |= __builtin_arm_stlex(42, (short *)addr);
+  res |= __builtin_arm_stlex(42, (int *)addr);
+  res |= __builtin_arm_stlex(42, (long long *)addr);
+  res |= __builtin_arm_stlex(42, (__int128 *)addr);
+  res |= __builtin_arm_stlex(2.71828f, (float *)addr);
+  res |= __builtin_arm_stlex(3.14159, (double *)addr);
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr);
+
+  res |= __builtin_arm_stlex(42, (volatile char *)addr);
+  res |= __builtin_arm_stlex(42, (char *const)addr);
+  res |= __builtin_arm_stlex(42, (const char *)addr); // expected-warning {{passing 'const char *' to parameter of type 'volatile char *' discards qualifiers}}
+
+
+  res |= __builtin_arm_stlex(var, (struct Simple *)addr); // expected-error {{address argument to atomic builtin must be a pointer to}}
+  res |= __builtin_arm_stlex(var, (struct Simple **)addr); // expected-error {{passing 'struct Simple' to parameter of incompatible type 'struct Simple *'}}
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr).a; // expected-error {{is not a structure or union}}
+
+  __builtin_arm_stlex(1); // expected-error {{too few arguments to function call}}
+  __builtin_arm_stlex(1, 2, 3); // expected-error {{too many arguments to function call}}
+  return res;
+}
+
 void test_clrex() {
   __builtin_arm_clrex();
   __builtin_arm_clrex(1); // expected-error {{too many arguments to function call}}
diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c
index 8ca33c8..7647100 100644
--- a/test/Sema/builtins.c
+++ b/test/Sema/builtins.c
@@ -197,3 +197,8 @@
   __noop(1); // expected-warning {{implicit declaration}}
   __debugbreak(); // expected-warning {{implicit declaration}}
 }
+
+void unavailable() {
+  __builtin_operator_new(0); // expected-error {{'__builtin_operator_new' is only available in C++}}
+  __builtin_operator_delete(0); // expected-error {{'__builtin_operator_delete' is only available in C++}}
+}
diff --git a/test/Sema/c89.c b/test/Sema/c89.c
index b746d38..c9e81f1 100644
--- a/test/Sema/c89.c
+++ b/test/Sema/c89.c
@@ -111,6 +111,8 @@
 
 void main() {} /* expected-error {{'main' must return 'int'}} */
 
+const int main() {} /* expected-error {{'main' must return 'int'}} */
+
 long long ll1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
          -42LL; /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
 unsigned long long ull1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
diff --git a/test/Sema/constant-builtins-2.c b/test/Sema/constant-builtins-2.c
index d2d221c..a4baecb 100644
--- a/test/Sema/constant-builtins-2.c
+++ b/test/Sema/constant-builtins-2.c
@@ -112,49 +112,53 @@
 //long double  g21 = __builtin_powil(2.0L, 4);
 
 #define BITSIZE(x) (sizeof(x) * 8)
-char g22[__builtin_clz(1) == BITSIZE(int) - 1 ? 1 : -1];
-char g23[__builtin_clz(7) == BITSIZE(int) - 3 ? 1 : -1];
-char g24[__builtin_clz(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1];
-int g25 = __builtin_clz(0); // expected-error {{not a compile-time constant}}
-char g26[__builtin_clzl(0xFL) == BITSIZE(long) - 4 ? 1 : -1];
-char g27[__builtin_clzll(0xFFLL) == BITSIZE(long long) - 8 ? 1 : -1];
+char clz1[__builtin_clz(1) == BITSIZE(int) - 1 ? 1 : -1];
+char clz2[__builtin_clz(7) == BITSIZE(int) - 3 ? 1 : -1];
+char clz3[__builtin_clz(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1];
+int clz4 = __builtin_clz(0); // expected-error {{not a compile-time constant}}
+char clz5[__builtin_clzl(0xFL) == BITSIZE(long) - 4 ? 1 : -1];
+char clz6[__builtin_clzll(0xFFLL) == BITSIZE(long long) - 8 ? 1 : -1];
+char clz7[__builtin_clzs(0x1) == BITSIZE(short) - 1 ? 1 : -1];
+char clz8[__builtin_clzs(0xf) == BITSIZE(short) - 4 ? 1 : -1];
+char clz9[__builtin_clzs(0xfff) == BITSIZE(short) - 12 ? 1 : -1];
 
-char g28[__builtin_ctz(1) == 0 ? 1 : -1];
-char g29[__builtin_ctz(8) == 3 ? 1 : -1];
-char g30[__builtin_ctz(1 << (BITSIZE(int) - 1)) == BITSIZE(int) - 1 ? 1 : -1];
-int g31 = __builtin_ctz(0); // expected-error {{not a compile-time constant}}
-char g32[__builtin_ctzl(0x10L) == 4 ? 1 : -1];
-char g33[__builtin_ctzll(0x100LL) == 8 ? 1 : -1];
+char ctz1[__builtin_ctz(1) == 0 ? 1 : -1];
+char ctz2[__builtin_ctz(8) == 3 ? 1 : -1];
+char ctz3[__builtin_ctz(1 << (BITSIZE(int) - 1)) == BITSIZE(int) - 1 ? 1 : -1];
+int ctz4 = __builtin_ctz(0); // expected-error {{not a compile-time constant}}
+char ctz5[__builtin_ctzl(0x10L) == 4 ? 1 : -1];
+char ctz6[__builtin_ctzll(0x100LL) == 8 ? 1 : -1];
+char ctz7[__builtin_ctzs(1 << (BITSIZE(short) - 1)) == BITSIZE(short) - 1 ? 1 : -1];
 
-char g34[__builtin_popcount(0) == 0 ? 1 : -1];
-char g35[__builtin_popcount(0xF0F0) == 8 ? 1 : -1];
-char g36[__builtin_popcount(~0) == BITSIZE(int) ? 1 : -1];
-char g37[__builtin_popcount(~0L) == BITSIZE(int) ? 1 : -1];
-char g38[__builtin_popcountl(0L) == 0 ? 1 : -1];
-char g39[__builtin_popcountl(0xF0F0L) == 8 ? 1 : -1];
-char g40[__builtin_popcountl(~0L) == BITSIZE(long) ? 1 : -1];
-char g41[__builtin_popcountll(0LL) == 0 ? 1 : -1];
-char g42[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
-char g43[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
+char popcount1[__builtin_popcount(0) == 0 ? 1 : -1];
+char popcount2[__builtin_popcount(0xF0F0) == 8 ? 1 : -1];
+char popcount3[__builtin_popcount(~0) == BITSIZE(int) ? 1 : -1];
+char popcount4[__builtin_popcount(~0L) == BITSIZE(int) ? 1 : -1];
+char popcount5[__builtin_popcountl(0L) == 0 ? 1 : -1];
+char popcount6[__builtin_popcountl(0xF0F0L) == 8 ? 1 : -1];
+char popcount7[__builtin_popcountl(~0L) == BITSIZE(long) ? 1 : -1];
+char popcount8[__builtin_popcountll(0LL) == 0 ? 1 : -1];
+char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
+char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
 
-char g44[__builtin_parity(0) == 0 ? 1 : -1];
-char g45[__builtin_parity(0xb821) == 0 ? 1 : -1];
-char g46[__builtin_parity(0xb822) == 0 ? 1 : -1];
-char g47[__builtin_parity(0xb823) == 1 ? 1 : -1];
-char g48[__builtin_parity(0xb824) == 0 ? 1 : -1];
-char g49[__builtin_parity(0xb825) == 1 ? 1 : -1];
-char g50[__builtin_parity(0xb826) == 1 ? 1 : -1];
-char g51[__builtin_parity(~0) == 0 ? 1 : -1];
-char g52[__builtin_parityl(1L << (BITSIZE(long) - 1)) == 1 ? 1 : -1];
-char g53[__builtin_parityll(1LL << (BITSIZE(long long) - 1)) == 1 ? 1 : -1];
+char parity1[__builtin_parity(0) == 0 ? 1 : -1];
+char parity2[__builtin_parity(0xb821) == 0 ? 1 : -1];
+char parity3[__builtin_parity(0xb822) == 0 ? 1 : -1];
+char parity4[__builtin_parity(0xb823) == 1 ? 1 : -1];
+char parity5[__builtin_parity(0xb824) == 0 ? 1 : -1];
+char parity6[__builtin_parity(0xb825) == 1 ? 1 : -1];
+char parity7[__builtin_parity(0xb826) == 1 ? 1 : -1];
+char parity8[__builtin_parity(~0) == 0 ? 1 : -1];
+char parity9[__builtin_parityl(1L << (BITSIZE(long) - 1)) == 1 ? 1 : -1];
+char parity10[__builtin_parityll(1LL << (BITSIZE(long long) - 1)) == 1 ? 1 : -1];
 
-char g54[__builtin_ffs(0) == 0 ? 1 : -1];
-char g55[__builtin_ffs(1) == 1 ? 1 : -1];
-char g56[__builtin_ffs(0xfbe71) == 1 ? 1 : -1];
-char g57[__builtin_ffs(0xfbe70) == 5 ? 1 : -1];
-char g58[__builtin_ffs(1U << (BITSIZE(int) - 1)) == BITSIZE(int) ? 1 : -1];
-char g59[__builtin_ffsl(0x10L) == 5 ? 1 : -1];
-char g60[__builtin_ffsll(0x100LL) == 9 ? 1 : -1];
+char ffs1[__builtin_ffs(0) == 0 ? 1 : -1];
+char ffs2[__builtin_ffs(1) == 1 ? 1 : -1];
+char ffs3[__builtin_ffs(0xfbe71) == 1 ? 1 : -1];
+char ffs4[__builtin_ffs(0xfbe70) == 5 ? 1 : -1];
+char ffs5[__builtin_ffs(1U << (BITSIZE(int) - 1)) == BITSIZE(int) ? 1 : -1];
+char ffs6[__builtin_ffsl(0x10L) == 5 ? 1 : -1];
+char ffs7[__builtin_ffsll(0x100LL) == 9 ? 1 : -1];
 #undef BITSIZE
 
 // GCC misc stuff
diff --git a/test/Sema/decl-in-prototype.c b/test/Sema/decl-in-prototype.c
index 9cb7fab..4f581aa 100644
--- a/test/Sema/decl-in-prototype.c
+++ b/test/Sema/decl-in-prototype.c
@@ -31,3 +31,7 @@
     struct z d;
     d.b = 4;
 }
+
+void pr19018_1 (enum e19018 { qq } x); // expected-warning{{declaration of 'enum e19018' will not be visible outside of this function}}
+enum e19018 qq; //expected-error{{tentative definition has type 'enum e19018' that is never completed}} \
+                //expected-note{{forward declaration of 'enum e19018'}}
diff --git a/test/Sema/dllimport.c b/test/Sema/dllimport.c
index f4d26fb..2702453 100644
--- a/test/Sema/dllimport.c
+++ b/test/Sema/dllimport.c
@@ -25,6 +25,9 @@
 int **__attribute__((dllimport))* GlobalDeclChunkAttr;
 int GlobalDeclAttr __attribute__((dllimport));
 
+// Address of variables can't be used for initialization in C language modes.
+int *VarForInit = &GlobalDecl; // expected-error{{initializer element is not a compile-time constant}}
+
 // Not allowed on definitions.
 __declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
 __declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
@@ -96,6 +99,11 @@
 void __attribute__((dllimport)) decl2A();
 void __declspec(dllimport)      decl2B();
 
+// Address of functions can be used for initialization in C language modes.
+// However, the address of the thunk wrapping the function is used instead of
+// the address in the import address table.
+void (*FunForInit)() = &decl2A;
+
 // Not allowed on function definitions.
 __declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
 
diff --git a/test/Sema/format-strings-enum-fixed-type.cpp b/test/Sema/format-strings-enum-fixed-type.cpp
index 8b6b237..0022ccb 100644
--- a/test/Sema/format-strings-enum-fixed-type.cpp
+++ b/test/Sema/format-strings-enum-fixed-type.cpp
@@ -16,7 +16,7 @@
 // This is why we don't check for that in the expected output.
 
 void test(TestEnum input) {
-  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'TestEnum'}}
+  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short'}}
   printf("%hhd", Constant); // expected-warning{{format specifies type 'char'}}
   
   printf("%hd", input); // no-warning
@@ -26,7 +26,7 @@
   printf("%d", input); // no-warning
   printf("%d", Constant); // no-warning
   
-  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'TestEnum'}}
+  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short'}}
   printf("%lld", Constant); // expected-warning{{format specifies type 'long long'}}
 }
 
@@ -34,7 +34,7 @@
 typedef enum : unsigned long { LongConstant = ~0UL } LongEnum;
 
 void testLong(LongEnum input) {
-  printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'LongEnum'}}
+  printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'unsigned long'}}
   printf("%u", LongConstant); // expected-warning{{format specifies type 'unsigned int'}}
   
   printf("%lu", input);
@@ -46,7 +46,7 @@
 typedef enum : short_t { ShortConstant = 0 } ShortEnum;
 
 void testUnderlyingTypedef(ShortEnum input) {
-  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'ShortEnum'}}
+  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short_t' (aka 'short')}}
   printf("%hhd", ShortConstant); // expected-warning{{format specifies type 'char'}}
   
   printf("%hd", input); // no-warning
@@ -56,7 +56,7 @@
   printf("%d", input); // no-warning
   printf("%d", ShortConstant); // no-warning
   
-  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'ShortEnum'}}
+  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short_t' (aka 'short')}}
   printf("%lld", ShortConstant); // expected-warning{{format specifies type 'long long'}}
 }
 
@@ -64,10 +64,10 @@
 typedef ShortEnum ShortEnum2;
 
 void testTypedefChain(ShortEnum2 input) {
-  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'ShortEnum2' (aka 'ShortEnum')}}
+  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short_t' (aka 'short')}}
   printf("%hd", input); // no-warning
   printf("%d", input); // no-warning
-  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'ShortEnum2' (aka 'ShortEnum')}}
+  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short_t' (aka 'short')}}
 }
 
 
@@ -80,13 +80,13 @@
   printf("%hhd", CharConstant); // no-warning
 
   // This is not correct but it is safe. We warn because '%hd' shows intent.
-  printf("%hd", input); // expected-warning{{format specifies type 'short' but the argument has type 'CharEnum'}}
+  printf("%hd", input); // expected-warning{{format specifies type 'short' but the argument has underlying type 'char'}}
   printf("%hd", CharConstant); // expected-warning{{format specifies type 'short'}}
   
   // This is not correct but it matches the promotion rules (and is safe).
   printf("%d", input); // no-warning
   printf("%d", CharConstant); // no-warning
   
-  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'CharEnum'}}
+  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'char'}}
   printf("%lld", CharConstant); // expected-warning{{format specifies type 'long long'}}
 }
diff --git a/test/Sema/format-strings-enum.c b/test/Sema/format-strings-enum.c
index a6c27d0..e79f859 100644
--- a/test/Sema/format-strings-enum.c
+++ b/test/Sema/format-strings-enum.c
@@ -20,7 +20,7 @@
     printf("%d", input); // no-warning
     printf("%d", Constant); // no-warning
 
-    printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'TestEnum'}}
+    printf("%lld", input); // expected-warning-re{{format specifies type 'long long' but the argument has underlying type '{{(unsigned)?}} int'}}
     printf("%lld", Constant); // expected-warning{{format specifies type 'long long'}}
 }
 
@@ -28,7 +28,7 @@
 typedef enum { LongConstant = ~0UL } LongEnum;
 
 void testLong(LongEnum input) {
-  printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'LongEnum'}}
+  printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type}}
   printf("%u", LongConstant); // expected-warning{{format specifies type 'unsigned int'}}
   
   printf("%lu", input);
diff --git a/test/Sema/ms-inline-asm.c b/test/Sema/ms-inline-asm.c
index deca650..66504aa 100644
--- a/test/Sema/ms-inline-asm.c
+++ b/test/Sema/ms-inline-asm.c
@@ -38,13 +38,11 @@
   // and do name lookup, if parsing failed, we did not restore the lexer state
   // properly.
 
-  // expected-error@+2 {{expected identifier}}
   __asm {
     and ecx, ~15
   }
 
   int x = 0;
-  // expected-error@+3 {{expected identifier}}
   __asm {
     and ecx, x
     and ecx, ~15
diff --git a/test/Sema/private-extern.c b/test/Sema/private-extern.c
index e9b67d5..0c13c92 100644
--- a/test/Sema/private-extern.c
+++ b/test/Sema/private-extern.c
@@ -13,10 +13,10 @@
 int g3; // expected-note{{previous definition}}
 static int g3; // expected-error{{static declaration of 'g3' follows non-static declaration}}
 
-extern int g4; // expected-note{{previous definition}}
+extern int g4; // expected-note{{previous declaration}}
 static int g4; // expected-error{{static declaration of 'g4' follows non-static declaration}}
 
-__private_extern__ int g5; // expected-note{{previous definition}}
+__private_extern__ int g5; // expected-note{{previous declaration}}
 static int g5; // expected-error{{static declaration of 'g5' follows non-static declaration}}
 
 void f0() {
@@ -30,12 +30,12 @@
 }
 
 void f2() {
-  extern int g8; // expected-note{{previous definition}}
+  extern int g8; // expected-note{{previous declaration}}
   int g8; // expected-error {{non-extern declaration of 'g8' follows extern declaration}}
 }
 
 void f3() {
-  __private_extern__ int g9; // expected-note{{previous definition}}
+  __private_extern__ int g9; // expected-note{{previous declaration}}
   int g9; // expected-error {{non-extern declaration of 'g9' follows extern declaration}}
 }
 
diff --git a/test/Sema/tentative-decls.c b/test/Sema/tentative-decls.c
index bf2b1e4..6026242 100644
--- a/test/Sema/tentative-decls.c
+++ b/test/Sema/tentative-decls.c
@@ -23,7 +23,7 @@
 int i1 = 2; // expected-error {{redefinition of 'i1'}}
 int i1;
 int i1;
-extern int i5; // expected-note {{previous definition is here}}
+extern int i5; // expected-note {{previous declaration is here}}
 static int i5; // expected-error{{static declaration of 'i5' follows non-static declaration}}
 
 static int i2 = 5; // expected-note 1 {{previous definition is here}}
@@ -49,7 +49,7 @@
 int redef[11]; // expected-error{{redefinition of 'redef'}}
 
 void func() {
-  extern int i6; // expected-note {{previous definition is here}}
+  extern int i6; // expected-note {{previous declaration is here}}
   static int i6; // expected-error{{static declaration of 'i6' follows non-static declaration}}
 }
 
diff --git a/test/Sema/thread-specifier.c b/test/Sema/thread-specifier.c
index d49b350..3968ae1 100644
--- a/test/Sema/thread-specifier.c
+++ b/test/Sema/thread-specifier.c
@@ -58,7 +58,7 @@
 }
 
 __thread typedef int t14; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local|thread_local}}' declaration specifier}}
-__thread int t15; // expected-note {{previous declaration is here}}
+__thread int t15; // expected-note {{previous definition is here}}
 extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}}
 extern int t16; // expected-note {{previous declaration is here}}
 __thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}}
diff --git a/test/Sema/var-redecl.c b/test/Sema/var-redecl.c
index 363458b..0e30aa2 100644
--- a/test/Sema/var-redecl.c
+++ b/test/Sema/var-redecl.c
@@ -58,5 +58,5 @@
 
 // PR3645
 static int a;
-extern int a; // expected-note {{previous definition is here}}
+extern int a; // expected-note {{previous declaration is here}}
 int a;	// expected-error {{non-static declaration of 'a' follows static declaration}}
diff --git a/test/Sema/warn-main-return-type.c b/test/Sema/warn-main-return-type.c
index c6f3a0c..f8bcbc5 100644
--- a/test/Sema/warn-main-return-type.c
+++ b/test/Sema/warn-main-return-type.c
@@ -22,8 +22,8 @@
   return 0.0;
 }
 
-// Currently we suggest to replace only 'float' here because we don't store
-// enough source locations.
+// TODO: Store qualifier source locations for return types so
+// we can replace the full type with this fix-it.
 //
 // expected-error@+3 {{conflicting types for 'main}}
 // expected-warning@+2 {{return type of 'main' is not 'int'}}
@@ -35,9 +35,11 @@
 
 typedef void *(*fptr)(int a);
 
-// expected-error@+2 {{conflicting types for 'main}}
-// expected-warning@+1 {{return type of 'main' is not 'int'}}
+// expected-error@+3 {{conflicting types for 'main}}
+// expected-warning@+2 {{return type of 'main' is not 'int'}}
+// expected-note@+1 {{change return type to 'int'}}
 fptr main() {
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:1-[[@LINE-1]]:5}:"int"
   return (fptr) 0;
 }
 
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index 3420d20..3b54c28 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -144,11 +144,14 @@
 void static_func(); // expected-note {{previous declaration is here}}
 
 
-static void static_func() // expected-warning {{static declaration of 'static_func' follows non-static declaration}}
+static void static_func() // expected-warning {{redeclaring non-static 'static_func' as static is a Microsoft extension}}
 {
 
 }
 
+extern const int static_var; // expected-note {{previous declaration is here}}
+static const int static_var = 3; // expected-warning {{redeclaring non-static 'static_var' as static is a Microsoft extension}}
+
 long function_prototype(int a);
 long (*function_ptr)(int a);
 
diff --git a/test/SemaCXX/PR19955.cpp b/test/SemaCXX/PR19955.cpp
new file mode 100644
index 0000000..cbbe2fe
--- /dev/null
+++ b/test/SemaCXX/PR19955.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i686-win32 -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple i686-mingw32 -verify -std=c++11 %s
+
+extern int __attribute__((dllimport)) var;
+constexpr int *varp = &var; // expected-error {{must be initialized by a constant expression}}
+
+extern __attribute__((dllimport)) void fun();
+constexpr void (*funp)(void) = &fun; // expected-error {{must be initialized by a constant expression}}
+
+template <void (*)()>
+struct S {};
+S<&fun> x;
+
+template <int *>
+struct U {};
+U<&var> y;
diff --git a/test/SemaCXX/PR20110.cpp b/test/SemaCXX/PR20110.cpp
new file mode 100644
index 0000000..e540a73
--- /dev/null
+++ b/test/SemaCXX/PR20110.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+// FIXME: These templates should trigger errors in C++11 mode.
+
+template <char const *p>
+class A {
+  char const *get_p() { return *p; }
+};
+template <int p>
+class B {
+  char const *get_p() { return p; }
+};
+
diff --git a/test/SemaCXX/__try.cpp b/test/SemaCXX/__try.cpp
index 1c45581..28a3701 100644
--- a/test/SemaCXX/__try.cpp
+++ b/test/SemaCXX/__try.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -fborland-extensions -fcxx-exceptions %s
-// expected-no-diagnostics
 
 // This test is from http://docwiki.embarcadero.com/RADStudio/en/Try
 
@@ -77,3 +76,14 @@
 template void Finally<void>();
 
 }
+
+void test___leave() {
+  // Most tests are in __try.c.
+
+  // Clang accepts try with __finally. MSVC doesn't. (Maybe a Borland thing?)
+  // __leave in mixed blocks isn't supported.
+  try {
+    __leave; // expected-error{{'__leave' statement not in __try block}}
+  } __finally {
+  }
+}
diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp
index f0b89ee..011f459 100644
--- a/test/SemaCXX/alignof.cpp
+++ b/test/SemaCXX/alignof.cpp
@@ -62,3 +62,18 @@
 long long int test14[2];
 
 static_assert(alignof(test14) == 8, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}}
+
+// PR19992
+static_assert(alignof(int[]) == alignof(int), ""); // ok
+
+namespace alignof_array_expr {
+  alignas(32) extern int n[];
+  static_assert(alignof(n) == 32, ""); // expected-warning {{GNU extension}}
+
+  template<int> struct S {
+    static int a[];
+  };
+  template<int N> int S<N>::a[N];
+  // ok, does not complete type of S<-1>::a
+  static_assert(alignof(S<-1>::a) == alignof(int), ""); // expected-warning {{GNU extension}}
+}
diff --git a/test/SemaCXX/anonymous-union-cxx11.cpp b/test/SemaCXX/anonymous-union-cxx11.cpp
index 9f987a9..b0dd1a8 100644
--- a/test/SemaCXX/anonymous-union-cxx11.cpp
+++ b/test/SemaCXX/anonymous-union-cxx11.cpp
@@ -12,3 +12,12 @@
     (void)sizeof(bar::member);
   }
 }
+
+namespace PR20021 {
+class C {
+  union {
+    static_assert(true, "");
+    int i;
+  };
+};
+}
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 574e9b3..09d93fa 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -823,6 +823,19 @@
 
 }
 
+struct This {
+  constexpr int f() const { return 0; }
+  static constexpr int g() { return 0; }
+  void h() {
+    constexpr int x = f(); // expected-error {{must be initialized by a constant}}
+    // expected-note@-1 {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}
+    constexpr int y = this->f(); // expected-error {{must be initialized by a constant}}
+    // expected-note-re@-1 {{{{^}}use of 'this' pointer}}
+    constexpr int z = g();
+    static_assert(z == 0, "");
+  }
+};
+
 }
 
 namespace Temporaries {
@@ -860,6 +873,12 @@
 constexpr bool b(int n) { return &n; }
 static_assert(b(0), "");
 
+struct NonLiteral {
+  NonLiteral();
+  int f();
+};
+constexpr int k = NonLiteral().f(); // expected-error {{constant expression}} expected-note {{non-literal type 'Temporaries::NonLiteral'}}
+
 }
 
 namespace Union {
diff --git a/test/SemaCXX/constructor.cpp b/test/SemaCXX/constructor.cpp
index f3b910d..fa930bd 100644
--- a/test/SemaCXX/constructor.cpp
+++ b/test/SemaCXX/constructor.cpp
@@ -17,6 +17,8 @@
   
   int Foo(int, int); // expected-error{{constructor cannot have a return type}} \
   // expected-error{{member 'Foo' has the same name as its class}}
+
+  volatile Foo(float); // expected-error{{constructor cannot have a return type}}
 };
 
 Foo::Foo(const Foo&) { }
diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp
index ffbd20f..a58a7f8 100644
--- a/test/SemaCXX/cxx0x-compat.cpp
+++ b/test/SemaCXX/cxx0x-compat.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++11-compat -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++11-compat -verify %s
 
 #if __cplusplus < 201103L
 
@@ -44,5 +44,6 @@
 #else
 
 auto init_capture = [a(0)] {}; // expected-warning {{initialized lambda captures are incompatible with C++ standards before C++1y}}
+static_assert(true); // expected-warning {{incompatible with C++ standards before C++1z}}
 
 #endif
diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp
index 75b2341..3ea5309 100644
--- a/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -375,3 +375,31 @@
   };
   B *p = new ({123}) B;
 }
+
+namespace PR11410 {
+  struct A {
+    A() = delete; // expected-note 2{{deleted here}}
+    A(int);
+  };
+
+  A a[3] = {
+    {1}, {2}
+  }; // expected-error {{call to deleted constructor}} \
+        expected-note {{in implicit initialization of array element 2 with omitted initializer}}
+
+  struct B {
+    A a; // expected-note {{in implicit initialization of field 'a'}}
+  } b = {
+  }; // expected-error {{call to deleted constructor}}
+
+  struct C {
+    C(int = 0); // expected-note 2{{candidate}}
+    C(float = 0); // expected-note 2{{candidate}}
+  };
+  C c[3] = {
+    0, 1
+  }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 2}}
+  C c2[3] = {
+    [0] = 1, [2] = 3
+  }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 1}}
+}
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp
new file mode 100644
index 0000000..7747457
--- /dev/null
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wsystem-headers %s
+
+// libstdc++4.6 in debug mode has explicit default constructors.
+// stlport has this for all containers.
+#ifdef BE_THE_HEADER
+#pragma clang system_header
+namespace std {
+namespace __debug {
+template <class T>
+class vector {
+public:
+  explicit vector() {} // expected-warning{{should not be explicit}}
+};
+}
+}
+#else
+
+#define BE_THE_HEADER
+#include __FILE__
+
+struct { int a, b; std::__debug::vector<int> c; } e[] = { {1, 1} }; // expected-note{{used in initialization here}}
+
+#endif
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 9d89cce..db6614d 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -230,3 +230,11 @@
   int f();
   std::initializer_list<long (*)()> x = {f}; // expected-error {{cannot initialize an array element of type 'long (*const)()' with an lvalue of type 'int ()': different return type ('long' vs 'int')}}
 }
+
+namespace DR1070 {
+  struct S {
+    S(std::initializer_list<int>);
+  };
+  S s[3] = { {1, 2, 3}, {4, 5} }; // ok
+  S *p = new S[3] { {1, 2, 3}, {4, 5} }; // ok
+}
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
index 8bd4f42..b08d58a 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
@@ -1358,6 +1358,21 @@
 int run_char = X<int>{}.foo('a');
 int run_int = X<double>{}.foo(4);
 }
-
 #endif // MS_EXTENSIONS
 
+namespace nsdmi_capturing_this {
+struct X {
+  int m = 10;
+  int n = [this](auto) { return m; }(20);
+};
+
+template<class T>
+struct XT {
+  T m = 10;
+  T n = [this](auto) { return m; }(20);
+};
+
+XT<int> xt{};
+
+
+}
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
new file mode 100644
index 0000000..b0b86e3
--- /dev/null
+++ b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
+
+namespace explicit_argument_variadics {
+
+
+template<class ... Ts> void print(Ts ... ) { }
+
+struct X { };
+struct Y { };
+struct Z { };
+
+int test() { 
+  {
+    auto L = [](auto ... as) { };
+    L.operator()<bool>(true);
+  }
+  {
+    auto L = [](auto a) { };
+    L.operator()<bool>(false);
+  }
+  {
+    auto L = [](auto a, auto b) { };
+    L.operator()<bool>(false, 'a');
+  }
+  {
+    auto L = [](auto a, auto b) { };
+    L.operator()<bool, char>(false, 'a');
+  }
+  {
+    auto L = [](auto a, auto b, auto ... cs) { };
+    L.operator()<bool, char>(false, 'a');
+    L.operator()<bool, char, const char*>(false, 'a', "jim");    
+  }
+
+  {
+    auto L = [](auto ... As) {
+    };
+    L.operator()<bool, double>(false, 3.14, "abc");
+  }
+  {
+    auto L = [](auto A, auto B, auto ... As) {
+    };
+    L.operator()<bool>(false, 3.14, "abc");
+    L.operator()<bool, char>(false, 3.14, "abc"); //expected-warning{{implicit conversion}}
+    L.operator()<X, Y, bool, Z>(X{}, Y{}, 3.14, Z{}, X{}); //expected-warning{{implicit conversion}}
+  }
+  {
+    auto L = [](auto ... As) {
+      print("\nL::As = ", As ...);
+      return [](decltype(As) ... as, auto ... Bs) {
+        print("\nL::Inner::as = ", as ...);
+        print("\nL::Inner::Bs = ", Bs ...);
+        return 4;
+      };
+    };
+    auto M = L.operator()<bool, double>(false, 3.14, "abc");
+    M(false, 6.26, "jim", true);
+    M.operator()<bool>(true, 6.26, "jim", false, 3.14);
+  }
+  {
+    auto L = [](auto A, auto ... As) {
+      print("\nL::As = ", As ...);
+      return [](decltype(As) ... as, decltype(A) a, auto ... Bs) {
+        print("\nL::Inner::as = ", as ...);
+        print("\nL::Inner::Bs = ", Bs ...);
+        return 4;
+      };
+    };
+    auto M = L.operator()<bool, double>(false, 3.14, "abc");
+    M(6.26, "jim", true);
+    M.operator()<X>(6.26, "jim", false, X{}, Y{}, Z{});
+  }
+  
+  return 0;
+}
+ int run = test();
+} // end ns explicit_argument_extension
+
+
+
+#ifdef PR18499_FIXED
+namespace variadic_expansion {
+  void f(int &, char &);
+
+  template <typename ... T> void g(T &... t) {
+    f([&a(t)]()->decltype(auto) {
+      return a;
+    }() ...);
+    f([&a(f([&b(t)]()->decltype(auto) { return b; }()...), t)]()->decltype(auto) {
+      return a;
+    }()...);
+  }
+
+  void h(int i, char c) { g(i, c); }
+}
+#endif
+
diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp
index 8c5e654..432c116 100644
--- a/test/SemaCXX/dcl_init_aggr.cpp
+++ b/test/SemaCXX/dcl_init_aggr.cpp
@@ -46,7 +46,7 @@
 };
 struct TooFewError { // expected-error{{implicit default constructor for}}
   int a;
-  NoDefaultConstructor nodef; // expected-note{{member is declared here}}
+  NoDefaultConstructor nodef; // expected-note{{member is declared here}} expected-note 2{{in implicit initialization of field 'nodef'}}
 };
 TooFewError too_few_okay = { 1, 1 };
 TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}}
@@ -54,7 +54,7 @@
 TooFewError too_few_okay2[2] = { 1, 1 }; // expected-note{{implicit default constructor for 'TooFewError' first required here}}
 TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}}
 
-NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}}
+NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}} expected-note {{implicit initialization of array element 0}}
 
 // C++ [dcl.init.aggr]p8
 struct Empty { };
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index d0a0731..5305ff5 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -380,3 +380,9 @@
 namespace PR16892 {
   auto p = &A::~A; // expected-error{{taking the address of a destructor}}
 }
+
+namespace PR20238 {
+struct S {
+  volatile ~S() { } // expected-error{{destructor cannot have a return type}}
+};
+}
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
index c361c49..9a53e27 100644
--- a/test/SemaCXX/dllexport.cpp
+++ b/test/SemaCXX/dllexport.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 %s
-// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 -DMS %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y -DMS %s
 // RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c++1y %s
 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
 
@@ -16,13 +16,13 @@
 
 
 // Invalid usage.
-__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
 #if __has_feature(cxx_strong_enums)
-  enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+  enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
 #endif
 
 
@@ -212,6 +212,10 @@
 namespace    { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}}
 namespace ns { __declspec(dllexport) void externalFunc() {} }
 
+// Export deleted function.
+__declspec(dllexport) void deletedFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+__declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -307,6 +311,105 @@
 
 
 //===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+class __declspec(dllexport) ClassDecl;
+
+class __declspec(dllexport) ClassDef {};
+
+#ifdef MS
+// expected-warning@+3{{'dllexport' attribute ignored}}
+#endif
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+
+template <typename T> struct ExpliciallySpecializedClassTemplate {};
+template <> struct __declspec(dllexport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
+
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> class ClassTemplate {};
+template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
+template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
+#endif
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
+#endif
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+// ClassTemplate<int> gets exported.
+class __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
+
+// ClassTemplate<int> is already exported.
+class __declspec(dllexport) DerivedFromTemplate2 : public ClassTemplate<int> {};
+
+// ExportedTemplate is explicitly exported.
+class __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+
+// ImportedTemplate is explicitly imported.
+class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<double>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is unsupported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class DerivedFromTemplateD : public ClassTemplate<double> {};
+class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<bool>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is unsupported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is unsupported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+
+// Base class already specialized with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is unsupported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+
+
+//===----------------------------------------------------------------------===//
 // Precedence
 //===----------------------------------------------------------------------===//
 
@@ -379,6 +482,17 @@
   __declspec(dllexport)                void protectedDef();
 private:
   __declspec(dllexport)                void privateDef();
+public:
+
+  __declspec(dllexport)                int  Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static         int  StaticFieldDef;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) static  const  int  StaticConstFieldDef;
+  __declspec(dllexport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllexport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+  __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
 };
 
        void ExportMembers::Nested::normalDef() {}
@@ -394,6 +508,10 @@
        void ExportMembers::protectedDef() {}
        void ExportMembers::privateDef() {}
 
+       int  ExportMembers::StaticFieldDef;
+const  int  ExportMembers::StaticConstFieldDef = 1;
+constexpr int ExportMembers::ConstexprFieldDef;
+
 
 // Export on member definitions.
 struct ExportMemberDefs {
@@ -406,6 +524,10 @@
   __declspec(dllexport) static         void staticDef();
   __declspec(dllexport) static         void staticInlineDef();
   __declspec(dllexport) static  inline void staticInlineDecl();
+
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
 };
 
 __declspec(dllexport)        void ExportMemberDefs::normalDef() {}
@@ -418,6 +540,10 @@
 __declspec(dllexport) inline void ExportMemberDefs::staticInlineDef() {}
 __declspec(dllexport)        void ExportMemberDefs::staticInlineDecl() {}
 
+__declspec(dllexport)        int  ExportMemberDefs::StaticField;
+__declspec(dllexport) const  int  ExportMemberDefs::StaticConstField = 1;
+__declspec(dllexport) constexpr int ExportMemberDefs::ConstexprField;
+
 
 // Export special member functions.
 struct ExportSpecials {
@@ -451,6 +577,18 @@
 void ExportAlloc::operator delete[](void* p) { free(p); }
 
 
+// Export deleted member functions.
+struct ExportDeleted {
+  __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+};
+
+
 // Export defaulted member functions.
 struct ExportDefaulted {
   __declspec(dllexport) ExportDefaulted() = default;
@@ -497,6 +635,10 @@
   static         void staticDef();         // expected-note{{previous declaration is here}}
   static         void staticInlineDef();   // expected-note{{previous declaration is here}}
   static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+  static         int  StaticField;         // expected-note{{previous declaration is here}}
+  static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
 };
 
 __declspec(dllexport)        void MemberRedecl::normalDef() {}         // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}}
@@ -509,6 +651,10 @@
 __declspec(dllexport) inline void MemberRedecl::staticInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
 __declspec(dllexport)        void MemberRedecl::staticInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
 
+__declspec(dllexport)        int  MemberRedecl::StaticField = 1;       // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}}
+__declspec(dllexport) const  int  MemberRedecl::StaticConstField = 1;  // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}}
+__declspec(dllexport) constexpr int MemberRedecl::ConstexprField;      // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -526,6 +672,17 @@
   template<typename T> __declspec(dllexport) static        void staticInclass() {}
   template<typename T> __declspec(dllexport) static        void staticInlineDef();
   template<typename T> __declspec(dllexport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+  template<typename T> __declspec(dllexport) static        int  StaticField;
+  template<typename T> __declspec(dllexport) static        int  StaticFieldDef;
+  template<typename T> __declspec(dllexport) static const  int  StaticConstField;
+  template<typename T> __declspec(dllexport) static const  int  StaticConstFieldDef;
+  template<typename T> __declspec(dllexport) static const  int  StaticConstFieldEqualInit = 1;
+  template<typename T> __declspec(dllexport) static const  int  StaticConstFieldBraceInit{1};
+  template<typename T> __declspec(dllexport) constexpr static int ConstexprField = 1;
+  template<typename T> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+#endif // __has_feature(cxx_variable_templates)
 };
 
 template<typename T>        void ExportMemberTmpl::normalDef() {}
@@ -535,6 +692,11 @@
 template<typename T> inline void ExportMemberTmpl::staticInlineDef() {}
 template<typename T>        void ExportMemberTmpl::staticInlineDecl() {}
 
+#if __has_feature(cxx_variable_templates)
+template<typename T>        int  ExportMemberTmpl::StaticFieldDef;
+template<typename T> const  int  ExportMemberTmpl::StaticConstFieldDef = 1;
+template<typename T> constexpr int ExportMemberTmpl::ConstexprFieldDef;
+#endif // __has_feature(cxx_variable_templates)
 
 
 // Redeclarations cannot add dllexport.
@@ -545,6 +707,12 @@
   template<typename T> static        void staticDef();         // expected-note{{previous declaration is here}}
   template<typename T> static        void staticInlineDef();   // expected-note{{previous declaration is here}}
   template<typename T> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+  template<typename T> static        int  StaticField;         // expected-note{{previous declaration is here}}
+  template<typename T> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
 };
 
 template<typename T> __declspec(dllexport)        void MemTmplRedecl::normalDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}}
@@ -554,6 +722,12 @@
 template<typename T> __declspec(dllexport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
 template<typename T> __declspec(dllexport)        void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
 
+#if __has_feature(cxx_variable_templates)
+template<typename T> __declspec(dllexport)        int  MemTmplRedecl::StaticField = 1;      // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) const  int  MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField;     // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+#endif // __has_feature(cxx_variable_templates)
+
 
 
 struct MemFunTmpl {
@@ -621,6 +795,52 @@
 
 
 
+#if __has_feature(cxx_variable_templates)
+struct MemVarTmpl {
+  template<typename T>                       static const int StaticVar = 1;
+  template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
+};
+template<typename T> const int MemVarTmpl::StaticVar;
+template<typename T> const int MemVarTmpl::ExportedStaticVar;
+
+// Export implicit instantiation of an exported member variable template.
+int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported member variable
+// template.
+extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+       template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported member variable
+// template.
+template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
+
+// Export specialization of an exported member variable template.
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported member variable template without
+// explicit dllexport.
+template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported member variable
+// template.
+extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+       template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported member variable
+// template.
+template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported member variable template.
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
 //===----------------------------------------------------------------------===//
 // Class template members
 //===----------------------------------------------------------------------===//
@@ -648,6 +868,17 @@
   __declspec(dllexport)                void protectedDef();
 private:
   __declspec(dllexport)                void privateDef();
+public:
+
+  __declspec(dllexport)                int  Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static         int  StaticFieldDef;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) static  const  int  StaticConstFieldDef;
+  __declspec(dllexport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllexport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+  __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
 };
 
 template<typename T>        void ExportClassTmplMembers<T>::normalDef() {}
@@ -662,6 +893,10 @@
 template<typename T>        void ExportClassTmplMembers<T>::protectedDef() {}
 template<typename T>        void ExportClassTmplMembers<T>::privateDef() {}
 
+template<typename T>        int  ExportClassTmplMembers<T>::StaticFieldDef;
+template<typename T> const  int  ExportClassTmplMembers<T>::StaticConstFieldDef = 1;
+template<typename T> constexpr int ExportClassTmplMembers<T>::ConstexprFieldDef;
+
 template struct ExportClassTmplMembers<ImplicitInst_Exported>;
 
 
@@ -677,6 +912,10 @@
   static         void staticDef();         // expected-note{{previous declaration is here}}
   static         void staticInlineDef();   // expected-note{{previous declaration is here}}
   static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+  static         int  StaticField;         // expected-note{{previous declaration is here}}
+  static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
 };
 
 template<typename T> __declspec(dllexport)        void CTMR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}}
@@ -689,6 +928,10 @@
 template<typename T> __declspec(dllexport) inline void CTMR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}}
 template<typename T> __declspec(dllexport)        void CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}}
 
+template<typename T> __declspec(dllexport)        int  CTMR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) const  int  CTMR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -707,6 +950,17 @@
   template<typename U> __declspec(dllexport) static        void staticInclass() {}
   template<typename U> __declspec(dllexport) static        void staticInlineDef();
   template<typename U> __declspec(dllexport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+  template<typename U> __declspec(dllexport) static        int  StaticField;
+  template<typename U> __declspec(dllexport) static        int  StaticFieldDef;
+  template<typename U> __declspec(dllexport) static const  int  StaticConstField;
+  template<typename U> __declspec(dllexport) static const  int  StaticConstFieldDef;
+  template<typename U> __declspec(dllexport) static const  int  StaticConstFieldEqualInit = 1;
+  template<typename U> __declspec(dllexport) static const  int  StaticConstFieldBraceInit{1};
+  template<typename U> __declspec(dllexport) constexpr static int ConstexprField = 1;
+  template<typename U> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+#endif // __has_feature(cxx_variable_templates)
 };
 
 template<typename T> template<typename U>        void ExportClsTmplMemTmpl<T>::normalDef() {}
@@ -716,6 +970,12 @@
 template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::staticInlineDef() {}
 template<typename T> template<typename U>        void ExportClsTmplMemTmpl<T>::staticInlineDecl() {}
 
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U>        int  ExportClsTmplMemTmpl<T>::StaticFieldDef;
+template<typename T> template<typename U> const  int  ExportClsTmplMemTmpl<T>::StaticConstFieldDef = 1;
+template<typename T> template<typename U> constexpr int ExportClsTmplMemTmpl<T>::ConstexprFieldDef;
+#endif // __has_feature(cxx_variable_templates)
+
 
 // Redeclarations cannot add dllexport.
 template<typename T>
@@ -726,6 +986,12 @@
   template<typename U> static        void staticDef();         // expected-note{{previous declaration is here}}
   template<typename U> static        void staticInlineDef();   // expected-note{{previous declaration is here}}
   template<typename U> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+  template<typename U> static        int  StaticField;         // expected-note{{previous declaration is here}}
+  template<typename U> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
 };
 
 template<typename T> template<typename U> __declspec(dllexport)        void CTMTR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}}
@@ -734,3 +1000,11 @@
 template<typename T> template<typename U> __declspec(dllexport)        void CTMTR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}}
 template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}}
 template<typename T> template<typename U> __declspec(dllexport)        void CTMTR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U> __declspec(dllexport)        int  CTMTR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) const  int  CTMTR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
+#endif // __has_feature(cxx_variable_templates)
+
+// FIXME: Precedence rules seem to be different for classes.
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
index 41f8e3c..855893c 100644
--- a/test/SemaCXX/dllimport.cpp
+++ b/test/SemaCXX/dllimport.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 %s
-// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 -DMS %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y -DMS %s
 // RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c++1y %s
 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
 
@@ -15,13 +15,13 @@
 
 
 // Invalid usage.
-__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
 #if __has_feature(cxx_strong_enums)
-  enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+  enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
 #endif
 
 
@@ -252,6 +252,13 @@
 namespace    { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
 namespace ns { __declspec(dllimport) void externalFunc(); }
 
+// Import deleted functions.
+// FIXME: Deleted functions are definitions so a missing inline is diagnosed
+// here which is irrelevant. But because the delete keyword is parsed later
+// there is currently no straight-forward way to avoid this diagnostic.
+__declspec(dllimport) void deletedFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -355,7 +362,6 @@
 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
 
 
-
 //===----------------------------------------------------------------------===//
 // Class members
 //===----------------------------------------------------------------------===//
@@ -387,6 +393,17 @@
   __declspec(dllimport)                void protectedDecl();
 private:
   __declspec(dllimport)                void privateDecl();
+public:
+
+  __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
+  __declspec(dllimport) static  const  int  StaticConstField;
+  __declspec(dllimport) static  const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
+  __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+  __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
 };
 
        void ImportMembers::Nested::normalDef() {} // expected-warning{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
@@ -400,6 +417,10 @@
 inline void ImportMembers::staticInlineDef() {}
        void ImportMembers::staticInlineDecl() {}
 
+       int  ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+const  int  ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
+constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+
 
 // Import on member definitions.
 struct ImportMemberDefs {
@@ -412,6 +433,10 @@
   __declspec(dllimport) static         void staticDef();
   __declspec(dllimport) static         void staticInlineDef();
   __declspec(dllimport) static  inline void staticInlineDecl();
+
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static  const  int  StaticConstField;
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
 };
 
 __declspec(dllimport)        void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
@@ -424,6 +449,10 @@
 __declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {}
 __declspec(dllimport)        void ImportMemberDefs::staticInlineDecl() {}
 
+__declspec(dllimport)        int  ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+__declspec(dllimport) const  int  ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+__declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+
 
 // Import special member functions.
 struct ImportSpecials {
@@ -436,6 +465,18 @@
 };
 
 
+// Import deleted member functions.
+struct ImportDeleted {
+  __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+};
+
+
 // Import allocation functions.
 struct ImportAlloc {
   __declspec(dllimport) void* operator new(__SIZE_TYPE__);
@@ -493,6 +534,10 @@
   static         void staticDef();         // expected-note{{previous declaration is here}}
   static         void staticInlineDef();   // expected-note{{previous declaration is here}}
   static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+  static         int  StaticField;         // expected-note{{previous declaration is here}}
+  static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
 };
 
 __declspec(dllimport)        void MemberRedecl::normalDef() {}         // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}
@@ -508,6 +553,16 @@
 __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
 __declspec(dllimport)        void MemberRedecl::staticInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
 
+__declspec(dllimport)        int  MemberRedecl::StaticField = 1;       // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                       // expected-note@-2{{attribute is here}}
+__declspec(dllimport) const  int  MemberRedecl::StaticConstField = 1;  // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                       // expected-note@-2{{attribute is here}}
+__declspec(dllimport) constexpr int MemberRedecl::ConstexprField;      // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                       // expected-note@-2{{attribute is here}}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -525,6 +580,17 @@
   template<typename T> __declspec(dllimport) static        void staticInclass() {}
   template<typename T> __declspec(dllimport) static        void staticInlineDef();
   template<typename T> __declspec(dllimport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+  template<typename T> __declspec(dllimport) static        int  StaticField;
+  template<typename T> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
+  template<typename T> __declspec(dllimport) static const  int  StaticConstField;
+  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
+  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
+  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
+  template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1;
+  template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
 };
 
 template<typename T>        void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
@@ -534,6 +600,12 @@
 template<typename T> inline void ImportMemberTmpl::staticInlineDef() {}
 template<typename T>        void ImportMemberTmpl::staticInlineDecl() {}
 
+#if __has_feature(cxx_variable_templates)
+template<typename T>        int  ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+template<typename T> const  int  ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
+template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+#endif // __has_feature(cxx_variable_templates)
+
 
 // Redeclarations cannot add dllimport.
 struct MemTmplRedecl {
@@ -543,6 +615,12 @@
   template<typename T> static        void staticDef();         // expected-note{{previous declaration is here}}
   template<typename T> static        void staticInlineDef();   // expected-note{{previous declaration is here}}
   template<typename T> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+  template<typename T> static        int  StaticField;         // expected-note{{previous declaration is here}}
+  template<typename T> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
 };
 
 template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}}
@@ -554,6 +632,18 @@
 template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
 template<typename T> __declspec(dllimport)        void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
 
+#if __has_feature(cxx_variable_templates)
+template<typename T> __declspec(dllimport)        int  MemTmplRedecl::StaticField = 1;      // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}}
+                                                                                            // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                            // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) const  int  MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}}
+                                                                                            // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                            // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField;     // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}}
+                                                                                            // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                            // expected-note@-2{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+
 
 
 struct MemFunTmpl {
@@ -628,6 +718,52 @@
 
 
 
+#if __has_feature(cxx_variable_templates)
+struct MemVarTmpl {
+  template<typename T>                       static const int StaticVar = 1;
+  template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
+};
+
+// Import implicit instantiation of an imported member variable template.
+int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }
+
+// Import explicit instantiation declaration of an imported member variable
+// template.
+extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of an imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of an imported member variable template.
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1;
+                                                                                // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                // expected-note@-2{{attribute is here}}
+
+// Not importing specialization of a member variable template without explicit
+// dllimport.
+template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
+
+
+// Import explicit instantiation declaration of a non-imported member variable
+// template.
+extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of a non-imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of a non-imported member variable template.
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1;
+                                                                                // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                // expected-note@-2{{attribute is here}}
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
 //===----------------------------------------------------------------------===//
 // Class template members
 //===----------------------------------------------------------------------===//
@@ -655,6 +791,17 @@
   __declspec(dllimport)                void protectedDecl();
 private:
   __declspec(dllimport)                void privateDecl();
+public:
+
+  __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
+  __declspec(dllimport) static  const  int  StaticConstField;
+  __declspec(dllimport) static  const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
+  __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+  __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
 };
 
 // NB: MSVC is inconsistent here and disallows *InlineDef on class templates,
@@ -669,6 +816,10 @@
 template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}
 template<typename T>        void ImportClassTmplMembers<T>::staticInlineDecl() {}
 
+template<typename T>        int  ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
+template<typename T> const  int  ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
+template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
+
 
 // Redeclarations cannot add dllimport.
 template<typename T>
@@ -682,6 +833,10 @@
   static         void staticDef();         // expected-note{{previous declaration is here}}
   static         void staticInlineDef();   // expected-note{{previous declaration is here}}
   static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+  static         int  StaticField;         // expected-note{{previous declaration is here}}
+  static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
 };
 
 template<typename T> __declspec(dllimport)        void CTMR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
@@ -697,6 +852,16 @@
 template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
 template<typename T> __declspec(dllimport)        void CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
 
+template<typename T> __declspec(dllimport)        int  CTMR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}}
+                                                                                       // expected-warning@-1{{definition of dllimport static field}}
+                                                                                       // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) const  int  CTMR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}}
+                                                                                       // expected-warning@-1{{definition of dllimport static field}}
+                                                                                       // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
+                                                                                       // expected-warning@-1{{definition of dllimport static field}}
+                                                                                       // expected-note@-2{{attribute is here}}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -715,6 +880,17 @@
   template<typename U> __declspec(dllimport) static        void staticInclass() {}
   template<typename U> __declspec(dllimport) static        void staticInlineDef();
   template<typename U> __declspec(dllimport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+  template<typename U> __declspec(dllimport) static        int  StaticField;
+  template<typename U> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
+  template<typename U> __declspec(dllimport) static const  int  StaticConstField;
+  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
+  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
+  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
+  template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1;
+  template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
 };
 
 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
@@ -724,6 +900,12 @@
 template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {}
 template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
 
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U>        int  ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> const  int  ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
+#endif // __has_feature(cxx_variable_templates)
+
 
 // Redeclarations cannot add dllimport.
 template<typename T>
@@ -734,6 +916,12 @@
   template<typename U> static        void staticDef();         // expected-note{{previous declaration is here}}
   template<typename U> static        void staticInlineDef();   // expected-note{{previous declaration is here}}
   template<typename U> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+  template<typename U> static        int  StaticField;         // expected-note{{previous declaration is here}}
+  template<typename U> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
 };
 
 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}
@@ -744,3 +932,154 @@
                                                                                                              // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
 template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
 template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U> __declspec(dllimport)        int  CTMTR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}}
+                                                                                                             // expected-warning@-1{{definition of dllimport static field}}
+                                                                                                             // expected-note@-2{{attribute is here}}
+template<typename T> template<typename U> __declspec(dllimport) const  int  CTMTR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}
+                                                                                                             // expected-warning@-1{{definition of dllimport static field}}
+                                                                                                             // expected-note@-2{{attribute is here}}
+template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}}
+                                                                                                             // expected-warning@-1{{definition of dllimport static field}}
+                                                                                                             // expected-note@-2{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+class __declspec(dllimport) ClassDecl;
+
+class __declspec(dllimport) ClassDef { };
+
+template <typename T> class ClassTemplate {};
+
+#ifdef MS
+// expected-note@+5{{previous attribute is here}}
+// expected-note@+4{{previous attribute is here}}
+// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}}
+// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}}
+#endif
+class __declspec(dllimport) ImportClassWithDllMember {
+  void __declspec(dllexport) foo();
+  void __declspec(dllimport) bar();
+};
+
+#ifdef MS
+// expected-note@+5{{previous attribute is here}}
+// expected-note@+4{{previous attribute is here}}
+// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}}
+// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}}
+#endif
+class __declspec(dllexport) ExportClassWithDllMember {
+  void __declspec(dllimport) foo();
+  void __declspec(dllexport) bar();
+};
+
+namespace ImportedExplicitSpecialization {
+template <typename T> struct S { static int x; };
+template <typename T> int S<T>::x = sizeof(T);
+template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}
+int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}}
+}
+
+namespace PR19988 {
+// Don't error about applying delete to dllimport member function when instantiating.
+template <typename> struct __declspec(dllimport) S {
+  void foo() = delete;
+};
+S<int> s;
+}
+
+#ifdef MS
+// expected-warning@+3{{'dllimport' attribute ignored}}
+#endif
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+
+template <typename T> struct ExpliciallySpecializedClassTemplate {};
+template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
+
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
+
+template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
+
+// ClassTemplate<int> gets imported.
+class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
+
+// ClassTemplate<int> is already imported.
+class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {};
+
+// ImportedClassTemplate is expliitly imported.
+class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+
+// ExportedClassTemplate is explicitly exported.
+class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<double>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is unsupported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class DerivedFromTemplateD : public ClassTemplate<double> {};
+class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<bool>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is unsupported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
+#endif
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
+#endif
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is unsupported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+
+// Base class already specialized with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+
+// Base class already specialized with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is unsupported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp
index b3cf9c3..329be63 100644
--- a/test/SemaCXX/for-range-examples.cpp
+++ b/test/SemaCXX/for-range-examples.cpp
@@ -176,8 +176,9 @@
 
     // Make sure these don't crash. Better diagnostics would be nice.
     for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
-    for (x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
-    for (y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
+    for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
+    for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
+    for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
   }
 }
 
@@ -209,3 +210,20 @@
       // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'test6::vector []' is treated as pointer type 'test6::vector *'}}
   }
 }
+
+namespace test7 {
+  void f() {
+    int arr[5], b;
+    for (a : arr) {} // expected-warning {{extension}}
+    // FIXME: Give a -Wshadow for this by default?
+    for (b : arr) {} // expected-warning {{extension}}
+    for (arr : arr) {} // expected-warning {{extension}}
+    for (c alignas(8) : arr) { // expected-warning {{extension}}
+      static_assert(alignof(c) == 8, ""); // expected-warning {{extension}}
+    }
+    // FIXME: We should reject this, but don't, because we only check the
+    // attribute before we deduce the 'auto' type.
+    for (d alignas(1) : arr) {} // expected-warning {{extension}}
+    for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-warning {{extension}}
+  }
+}
diff --git a/test/SemaCXX/microsoft-dtor-lookup.cpp b/test/SemaCXX/microsoft-dtor-lookup.cpp
index 51129ae..412749f 100644
--- a/test/SemaCXX/microsoft-dtor-lookup.cpp
+++ b/test/SemaCXX/microsoft-dtor-lookup.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only %s
-// RUN: %clang_cc1 -triple %ms_abi_triple -verify %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %itanium_abi_triple -fsyntax-only %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %ms_abi_triple -verify %s
 
 namespace Test1 {
 
@@ -37,11 +37,11 @@
 // though MSVC rejects bar.
 class A {
 private:
-  ~A(); // expected-note {{declared private here}}
+  ~A();
   int a;
 };
 
-struct B : public A { // expected-error {{base class 'Test2::A' has private destructor}}
+struct B : public A { // expected-note {{destructor of 'B' is implicitly deleted because base class 'Test2::A' has an inaccessible destructor}}
   int b;
 };
 
@@ -55,7 +55,7 @@
   C o;
 };
 
-void foo(B b) { } // expected-note {{implicit destructor for 'Test2::B' first required here}}
+void foo(B b) { } // expected-error {{attempt to use a deleted function}}
 void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check.
 void baz(D d) { } // no error
 
@@ -87,3 +87,45 @@
 class A;
 void foo(A a);
 }
+
+#ifdef MSVC_ABI
+namespace Test5 {
+// Do the operator delete access control check from the context of the dtor.
+class A {
+ protected:
+  void operator delete(void *);
+};
+class B : public A {
+  virtual ~B();
+};
+B *test() {
+  // Previously, marking the vtable used here would do the operator delete
+  // lookup from this context, which doesn't have access.
+  return new B;
+}
+}
+#endif
+
+namespace Test6 {
+class A {
+protected:
+  void operator delete(void *);
+};
+class B : public A {
+  virtual ~B();
+public:
+  virtual void m_fn1();
+};
+void fn1(B *b) { b->m_fn1(); }
+}
+
+namespace Test7 {
+class A {
+protected:
+  void operator delete(void *);
+};
+struct B : public A {
+  virtual ~B();
+};
+void fn1(B b) {}
+}
diff --git a/test/SemaCXX/ms_integer_suffix.cpp b/test/SemaCXX/ms_integer_suffix.cpp
new file mode 100644
index 0000000..6b4594d
--- /dev/null
+++ b/test/SemaCXX/ms_integer_suffix.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fms-extensions -verify %s
+// expected-no-diagnostics
+
+#ifdef __SIZEOF_INT8__
+static_assert(sizeof(0i8) == __SIZEOF_INT8__, "");
+#endif
+#ifdef __SIZEOF_INT16__
+static_assert(sizeof(0i16) == __SIZEOF_INT16__, "");
+#endif
+#ifdef __SIZEOF_INT32__
+static_assert(sizeof(0i32) == __SIZEOF_INT32__, "");
+#endif
+#ifdef __SIZEOF_INT64__
+static_assert(sizeof(0i64) == __SIZEOF_INT64__, "");
+#endif
+#ifdef __SIZEOF_INT128__
+static_assert(sizeof(0i128) == __SIZEOF_INT128__, "");
+#endif
diff --git a/test/SemaCXX/new-delete-cxx0x.cpp b/test/SemaCXX/new-delete-cxx0x.cpp
index c404fab..899cb4c 100644
--- a/test/SemaCXX/new-delete-cxx0x.cpp
+++ b/test/SemaCXX/new-delete-cxx0x.cpp
@@ -2,8 +2,8 @@
 
 void ugly_news(int *ip) {
   // These are ill-formed according to one reading of C++98, and at the least
-  // have undefined behavior. But they're well-formed, and defined to throw
-  // std::bad_array_new_length, in C++11.
+  // have undefined behavior.
+  // FIXME: They're ill-formed in C++11.
   (void)new int[-1]; // expected-warning {{array size is negative}}
   (void)new int[2000000000]; // expected-warning {{array is too large}}
 }
@@ -22,5 +22,12 @@
 void fn() {
   (void) new int[2] {1, 2};
   (void) new S[2] {1, 2};
-  (void) new T[2] {1, 2}; // expected-error {{no matching constructor}}
+  // C++11 [expr.new]p19:
+  //   If the new-expression creates an object or an array of objects of class
+  //   type, access and ambiguity control are done for the allocation function,
+  //   the deallocation function (12.5), and the constructor (12.1).
+  //
+  // Note that this happens even if the array bound is constant and the
+  // initializer initializes every array element.
+  (void) new T[2] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 2}}
 }
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 175ebe7..cb43458 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -521,3 +521,6 @@
 namespace PR18544 {
   inline void *operator new(size_t); // expected-error {{'operator new' cannot be declared inside a namespace}}
 }
+
+// PR19968
+inline void* operator new(); // expected-error {{'operator new' must have at least one parameter}}
diff --git a/test/SemaCXX/ns_returns_retained_block_return.cpp b/test/SemaCXX/ns_returns_retained_block_return.cpp
new file mode 100644
index 0000000..9d04536
--- /dev/null
+++ b/test/SemaCXX/ns_returns_retained_block_return.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fsyntax-only -verify %s
+// expected-no-diagnostics
+// rdar://17259812
+
+typedef void (^BT) ();
+
+class S {
+  BT br() __attribute__((ns_returns_retained)) {
+    return ^{};
+  }
+ BT br1() __attribute__((ns_returns_retained));
+};
+
+BT S::br1() {
+    return ^{};
+}
diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp
index 4a7560b..7de4d07 100644
--- a/test/SemaCXX/static-assert.cpp
+++ b/test/SemaCXX/static-assert.cpp
@@ -48,3 +48,6 @@
 struct X { ~X(); };
 StaticAssertProtected<int> sap1;
 StaticAssertProtected<X> sap2; // expected-note {{instantiation}}
+
+static_assert(true); // expected-warning {{C++1z extension}}
+static_assert(false); // expected-error-re {{failed{{$}}}} expected-warning {{extension}}
diff --git a/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp b/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
new file mode 100644
index 0000000..9a16f2b
--- /dev/null
+++ b/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 -Wimplicit-fallthrough %s
+
+void fallthrough_in_blocks() {
+  void (^block)() = ^{
+    int x = 0;
+    switch (x) {
+    case 0:
+      x++;
+      [[clang::fallthrough]]; // no diagnostics
+    case 1:
+      x++;
+    default: // \
+        expected-warning{{unannotated fall-through between switch labels}} \
+        expected-note{{insert 'break;' to avoid fall-through}}
+      break;
+    }
+  };
+  block();
+}
diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp
index 831324a..0bc43cd 100644
--- a/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ b/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -229,6 +229,59 @@
   return n;
 }
 
+// Fallthrough annotations in local classes used to generate "fallthrough
+// annotation does not directly precede switch label" warning.
+void fallthrough_in_local_class() {
+  class C {
+    void f(int x) {
+      switch (x) {
+        case 0:
+          x++;
+          [[clang::fallthrough]]; // no diagnostics
+        case 1:
+          x++;
+        default: // \
+            expected-warning{{unannotated fall-through between switch labels}} \
+            expected-note{{insert 'break;' to avoid fall-through}}
+          break;
+      }
+    }
+  };
+}
+
+// Fallthrough annotations in lambdas used to generate "fallthrough
+// annotation does not directly precede switch label" warning.
+void fallthrough_in_lambda() {
+  (void)[] {
+    int x = 0;
+    switch (x) {
+    case 0:
+      x++;
+      [[clang::fallthrough]]; // no diagnostics
+    case 1:
+      x++;
+    default: // \
+        expected-warning{{unannotated fall-through between switch labels}} \
+        expected-note{{insert 'break;' to avoid fall-through}}
+      break;
+    }
+  };
+}
+
+namespace PR18983 {
+  void fatal() __attribute__((noreturn));
+  int num();
+  void test() {
+    switch (num()) {
+    case 1:
+      fatal();
+      // Don't issue a warning.
+    case 2:
+      break;
+    }
+  }
+}
+
 int fallthrough_targets(int n) {
   [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
 
@@ -247,34 +300,3 @@
   }
   return n;
 }
-
-// Fallthrough annotations in local classes used to generate "fallthrough
-// annotation does not directly precede switch label" warning.
-void fallthrough_in_local_class() {
-  class C {
-    void f(int x) {
-      switch (x) {
-        case 0:
-          x++;
-          [[clang::fallthrough]]; // no diagnostics
-        case 1:
-          x++;
-          break;
-      }
-    }
-  };
-}
-
-namespace PR18983 {
-  void fatal() __attribute__((noreturn));
-  int num();
-  void test() {
-    switch (num()) {
-    case 1:
-      fatal();
-      // Don't issue a warning.
-    case 2:
-      break;
-    }
-  }
-}
diff --git a/test/SemaCXX/template-implicit-vars.cpp b/test/SemaCXX/template-implicit-vars.cpp
index a8e8bf7..25d35fb 100644
--- a/test/SemaCXX/template-implicit-vars.cpp
+++ b/test/SemaCXX/template-implicit-vars.cpp
@@ -8,7 +8,7 @@
 void g() {
   f(1);
 }
-// CHECK: VarDecl {{.*}} implicit __range
-// CHECK: VarDecl {{.*}} implicit __range
-// CHECK: VarDecl {{.*}} implicit __begin
-// CHECK: VarDecl {{.*}} implicit __end
+// CHECK: VarDecl {{.*}} implicit used __range
+// CHECK: VarDecl {{.*}} implicit used __range
+// CHECK: VarDecl {{.*}} implicit used __begin
+// CHECK: VarDecl {{.*}} implicit used __end
diff --git a/test/SemaCXX/type-definition-in-specifier.cpp b/test/SemaCXX/type-definition-in-specifier.cpp
index bda91d9..43443a0 100644
--- a/test/SemaCXX/type-definition-in-specifier.cpp
+++ b/test/SemaCXX/type-definition-in-specifier.cpp
@@ -23,3 +23,44 @@
 struct S5 { int x; } f1() { return S5(); } // expected-error{{result type}}
 
 void f2(struct S6 { int x; } p); // expected-error{{parameter type}}
+
+struct pr19018 {
+  short foo6 (enum bar0 {qq} bar3); // expected-error{{cannot be defined in a parameter type}}
+};
+
+void pr19018_1 (enum e19018_1 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_1a (enum e19018_1 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+e19018_1 x2;  // expected-error{{unknown type name 'e19018_1'}}
+
+void pr19018_2 (enum {qq} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_3 (struct s19018_2 {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_4 (struct {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_5 (struct { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_5 (struct s19018_2 { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+
+struct pr19018a {
+  static int xx;
+  void func1(enum t19018 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+  void func2(enum t19018 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+  void func3(enum {qq} x);        // expected-error{{cannot be defined in a parameter type}}
+  void func4(struct t19018 {int qq;} x);  // expected-error{{cannot be defined in a parameter type}}
+  void func5(struct {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+  void func6(struct { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+  void func7(struct t19018 { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+  void func8(struct { int qq() { return xx; }; } x); // expected-error{{cannot be defined in a parameter type}}
+  void func9(struct t19018 { int qq() { return xx; }; } x); // expected-error{{cannot be defined in a parameter type}}
+};
+
+struct s19018b {
+  void func1 (enum en_2 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+  en_2 x1;  // expected-error{{unknown type name 'en_2'}}
+  void func2 (enum en_3 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+  enum en_3 x2; // expected-error{{ISO C++ forbids forward references to 'enum' types}} \
+                // expected-error{{field has incomplete type 'enum en_3'}} \
+                // expected-note{{forward declaration of 'en_3'}}
+};
+
+struct pr18963 {
+  short bar5 (struct foo4 {} bar2); // expected-error{{'foo4' cannot be defined in a parameter type}}
+  long foo5 (float foo6 = foo4);  // expected-error{{use of undeclared identifier 'foo4'}}
+};
diff --git a/test/SemaCXX/typo-correction-pt2.cpp b/test/SemaCXX/typo-correction-pt2.cpp
index 2fab22a..88a7073 100644
--- a/test/SemaCXX/typo-correction-pt2.cpp
+++ b/test/SemaCXX/typo-correction-pt2.cpp
@@ -5,6 +5,15 @@
 // attempt within a single file (which is to avoid having very broken files take
 // minutes to finally be rejected by the parser).
 
+namespace PR12951 {
+// If there are two corrections that have the same identifier and edit distance
+// and only differ by their namespaces, don't suggest either as a correction
+// since both are equally likely corrections.
+namespace foobar { struct Thing {}; }
+namespace bazquux { struct Thing {}; }
+void f() { Thing t; } // expected-error{{unknown type name 'Thing'}}
+}
+
 namespace bogus_keyword_suggestion {
 void test() {
    status = "OK";  // expected-error-re {{use of undeclared identifier 'status'{{$}}}}
@@ -278,3 +287,16 @@
   if (p)  // expected-error-re {{use of undeclared identifier 'p'{{$}}}}
     return;
 }
+
+namespace PR19681 {
+  struct TypoA {};
+  struct TypoB {
+    void test();
+  private:
+    template<typename T> void private_memfn(T);  // expected-note{{declared here}}
+  };
+  void TypoB::test() {
+    // FIXME: should suggest 'PR19681::TypoB::private_memfn' instead of '::PR19681::TypoB::private_memfn'
+    (void)static_cast<void(TypoB::*)(int)>(&TypoA::private_memfn);  // expected-error{{no member named 'private_memfn' in 'PR19681::TypoA'; did you mean '::PR19681::TypoB::private_memfn'?}}
+  }
+}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 8541356..e8160b0 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -202,15 +202,6 @@
   };
 }
 
-namespace PR12951 {
-// If there are two corrections that have the same identifier and edit distance
-// and only differ by their namespaces, don't suggest either as a correction
-// since both are equally likely corrections.
-namespace foobar { struct Thing {}; }
-namespace bazquux { struct Thing {}; }
-void f() { Thing t; } // expected-error{{unknown type name 'Thing'}}
-}
-
 namespace PR13051 {
   template<typename T> struct S {
     template<typename U> void f();
diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp
index 1cb0708..f32036a 100644
--- a/test/SemaCXX/undefined-internal.cpp
+++ b/test/SemaCXX/undefined-internal.cpp
@@ -1,10 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // Make sure we don't produce invalid IR.
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s
-
-// FIXME: Itanium shouldn't be necessary; the test should pass
-// in MS mode too.
+// RUN: %clang_cc1 -emit-llvm-only %s
 
 namespace test1 {
   static void foo(); // expected-warning {{function 'test1::foo' has internal linkage but is not defined}}
diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp
index 7bca06b..2a972b1 100644
--- a/test/SemaCXX/underlying_type.cpp
+++ b/test/SemaCXX/underlying_type.cpp
@@ -41,3 +41,17 @@
  
 static_assert(is_same_type<underlying_type<foo>::type, unsigned>::value,
               "foo has the wrong underlying type");
+
+namespace PR19966 {
+  void PR19966(enum Invalid) { // expected-note 2{{forward declaration of}}
+    // expected-error@-1 {{ISO C++ forbids forward references to 'enum'}}
+    // expected-error@-2 {{variable has incomplete type}}
+    __underlying_type(Invalid) dont_crash;
+    // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::Invalid'}}
+  }
+  enum E { // expected-note {{forward declaration of 'E'}}
+    a = (__underlying_type(E)){}
+    // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::E'}}
+    // expected-error@-2 {{constant expression}}
+  };
+}
diff --git a/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp
index 687bfd2..4dcd348 100644
--- a/test/SemaCXX/uninit-variables.cpp
+++ b/test/SemaCXX/uninit-variables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify
+// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify -std=c++1y
 
 // Stub out types for 'typeid' to work.
 namespace std { class type_info {}; }
@@ -147,3 +147,6 @@
   consume_const_ref(n);
   return n; // expected-warning {{uninitialized when used here}}
 }
+
+// Don't crash here.
+auto PR19996 = [a=0]{int t; return a;};
diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp
index 7a7459a..e86610a 100644
--- a/test/SemaCXX/warn-bad-memaccess.cpp
+++ b/test/SemaCXX/warn-bad-memaccess.cpp
@@ -24,6 +24,11 @@
 struct X1 { virtual void f(); } x1;
 struct X2 : virtual S1 {} x2;
 
+struct ContainsDynamic { X1 dynamic; } contains_dynamic;
+struct DeepContainsDynamic { ContainsDynamic m; } deep_contains_dynamic;
+struct ContainsArrayDynamic { X1 dynamic[1]; } contains_array_dynamic;
+struct ContainsPointerDynamic { X1 *dynamic; } contains_pointer_dynamic;
+
 void test_warn() {
   memset(&x1, 0, sizeof x1); // \
       // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
@@ -33,22 +38,22 @@
       // expected-note {{explicitly cast the pointer to silence this warning}}
 
   memmove(&x1, 0, sizeof x1); // \
-      // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
+      // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memmove(0, &x1, sizeof x1); // \
-      // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be moved}} \
+      // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be moved}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcpy(&x1, 0, sizeof x1); // \
-      // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
+      // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcpy(0, &x1, sizeof x1); // \
-      // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be copied}} \
+      // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be copied}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcmp(&x1, 0, sizeof x1); // \
-      // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
+      // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcmp(0, &x1, sizeof x1); // \
-      // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
+      // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
 
   __builtin_memset(&x1, 0, sizeof x1); // \
@@ -90,6 +95,16 @@
   __builtin___memcpy_chk(0, &x1, sizeof x1, sizeof x1); //                    \
       // expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
+
+  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+  memset(&contains_dynamic, 0, sizeof(contains_dynamic));
+  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+  memset(&deep_contains_dynamic, 0, sizeof(deep_contains_dynamic));
+  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+  memset(&contains_array_dynamic, 0, sizeof(contains_array_dynamic));
 }
 
 void test_nowarn(void *void_ptr) {
@@ -107,6 +122,8 @@
   memset(&s3, 0, sizeof s3);
   memset(&c1, 0, sizeof c1);
 
+  memset(&contains_pointer_dynamic, 0, sizeof(contains_pointer_dynamic));
+
   // Unevaluated code shouldn't warn.
   (void)sizeof memset(&x1, 0, sizeof x1);
 
diff --git a/test/SemaCXX/warn-self-assign.cpp b/test/SemaCXX/warn-self-assign.cpp
index fcdb2ab..7d558c6 100644
--- a/test/SemaCXX/warn-self-assign.cpp
+++ b/test/SemaCXX/warn-self-assign.cpp
@@ -8,6 +8,9 @@
   b = a = b;
   a = a = a; // expected-warning{{explicitly assigning}}
   a = b = b = a;
+  a &= a; // expected-warning{{explicitly assigning}}
+  a |= a; // expected-warning{{explicitly assigning}}
+  a ^= a;
 }
 
 // Dummy type.
diff --git a/test/SemaCXX/warn-tautological-undefined-compare.cpp b/test/SemaCXX/warn-tautological-undefined-compare.cpp
new file mode 100644
index 0000000..ce05bfc
--- /dev/null
+++ b/test/SemaCXX/warn-tautological-undefined-compare.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-undefined-compare %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-tautological-compare -Wtautological-undefined-compare %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-compare %s
+
+void test1(int &x) {
+  if (x == 1) { }
+  if (&x == 0) { }
+  // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+  if (&x != 0) { }
+  // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+}
+
+class test2 {
+  test2() : x(y) {}
+
+  void foo() {
+    if (this == 0) { }
+    // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (this != 0) { }
+    // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+  }
+
+  void bar() {
+    if (x == 1) { }
+    if (&x == 0) { }
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&x != 0) { }
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+  }
+
+  int &x;
+  int y;
+};
+
+namespace function_return_reference {
+  int& get_int();
+  // expected-note@-1 4{{'get_int' returns a reference}}
+  class B {
+  public:
+    static int &stat();
+    // expected-note@-1 4{{'stat' returns a reference}}
+    int &get();
+    // expected-note@-1 8{{'get' returns a reference}}
+  };
+
+  void test() {
+    if (&get_int() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&(get_int()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&get_int() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&(get_int()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    if (&B::stat() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&(B::stat()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&B::stat() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&(B::stat()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    B b;
+    if (&b.get() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&(b.get()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&b.get() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&(b.get()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    B* b_ptr = &b;
+    if (&b_ptr->get() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&(b_ptr->get()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&b_ptr->get() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&(b_ptr->get()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    int& (B::*m_ptr)() = &B::get;
+    if (&(b.*m_ptr)() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&((b.*m_ptr)()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&(b.*m_ptr)() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&((b.*m_ptr)()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    int& (*f_ptr)() = &get_int;
+    if (&(*f_ptr)() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&((*f_ptr)()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&(*f_ptr)() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&((*f_ptr)()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+  }
+}
diff --git a/test/SemaCXX/warn-undefined-bool-conversion.cpp b/test/SemaCXX/warn-undefined-bool-conversion.cpp
new file mode 100644
index 0000000..1f8baa0
--- /dev/null
+++ b/test/SemaCXX/warn-undefined-bool-conversion.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-bool-conversion %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion -Wundefined-bool-conversion %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wbool-conversion %s
+
+void test1(int &x) {
+  if (x == 1) { }
+  if (&x) { }
+  // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+  if (!&x) { }
+  // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+}
+
+class test2 {
+  test2() : x(y) {}
+
+  void foo() {
+    if (this) { }
+    // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    if (!this) { }
+    // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
+  }
+
+  void bar() {
+    if (x == 1) { }
+    if (&x) { }
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    if (!&x) { }
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+  }
+
+  int &x;
+  int y;
+};
+
+namespace function_return_reference {
+  int& get_int();
+  // expected-note@-1 3{{'get_int' returns a reference}}
+  class B {
+  public:
+    static int &stat();
+    // expected-note@-1 3{{'stat' returns a reference}}
+    int &get();
+    // expected-note@-1 6{{'get' returns a reference}}
+  };
+
+  void test() {
+    if (&get_int()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&(get_int())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&get_int()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    if (&B::stat()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&(B::stat())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&B::stat()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    B b;
+    if (&b.get()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&(b.get())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&b.get()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    B* b_ptr = &b;
+    if (&b_ptr->get()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&(b_ptr->get())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&b_ptr->get()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    int& (B::*m_ptr)() = &B::get;
+    if (&(b.*m_ptr)()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&((b.*m_ptr)())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&(b.*m_ptr)()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    int& (*f_ptr)() = &get_int;
+    if (&(*f_ptr)()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&((*f_ptr)())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&(*f_ptr)()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+  }
+}
diff --git a/test/SemaCXX/windows-arm-valist.cpp b/test/SemaCXX/windows-arm-valist.cpp
new file mode 100644
index 0000000..d12be65
--- /dev/null
+++ b/test/SemaCXX/windows-arm-valist.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple thumbv7--windows-msvc -std=c++11 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+#include <stdarg.h>
+
+template <typename lhs_, typename rhs_>
+struct is_same { enum { value = 0 }; };
+
+template <typename type_>
+struct is_same<type_, type_> { enum { value = 1 }; };
+
+void check() {
+  va_list va;
+  char *cp;
+  static_assert(is_same<decltype(va), decltype(cp)>::value,
+                "type mismatch for va_list");
+}
diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m
index 060af24..ba7c09f 100644
--- a/test/SemaObjC/arc.m
+++ b/test/SemaObjC/arc.m
@@ -285,7 +285,7 @@
   b = (nil == vp);
 
   b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}}
-  b = (op == vp); // expected-error {{implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRelease call}}
+  b = (op == vp);
 }
 
 void test12(id collection) {
@@ -782,3 +782,19 @@
     }
   }
 }
+
+// rdar://16627903
+extern void abort();
+#define TKAssertEqual(a, b) do{\
+    __typeof(a) a_res = (a);\
+    __typeof(b) b_res = (b);\
+    if ((a_res) != (b_res)) {\
+        abort();\
+    }\
+}while(0)
+
+int garf() {
+  id object;
+  TKAssertEqual(object, nil);
+  TKAssertEqual(object, (id)nil);
+}
diff --git a/test/SemaObjC/block-type-safety.m b/test/SemaObjC/block-type-safety.m
index 56342ba..b2c4398 100644
--- a/test/SemaObjC/block-type-safety.m
+++ b/test/SemaObjC/block-type-safety.m
@@ -23,6 +23,7 @@
 }
 
 @protocol NSObject;
+@class NSObject;
 
 void r2 (id<NSObject> (^f) (void)) {
   id o = f();
@@ -155,3 +156,45 @@
         return NSOrderedSame;
    }];
 }
+
+// rdar://16739120
+@protocol P1 @end
+@protocol P2 @end
+
+void Test() {
+void (^aBlock)();
+id anId = aBlock;  // OK
+
+id<P1,P2> anQualId = aBlock;  // expected-error {{initializing 'id<P1,P2>' with an expression of incompatible type 'void (^)()'}}
+
+NSArray* anArray = aBlock; // expected-error {{initializing 'NSArray *' with an expression of incompatible type 'void (^)()'}}
+
+aBlock = anId; // OK
+
+id<P1,P2> anQualId1;
+aBlock = anQualId1; // expected-error {{assigning to 'void (^)()' from incompatible type 'id<P1,P2>'}}
+
+NSArray* anArray1;
+aBlock = anArray1; // expected-error {{assigning to 'void (^)()' from incompatible type 'NSArray *'}}
+}
+
+void Test2() {
+  void (^aBlock)();
+  id<NSObject> anQualId1 = aBlock; // Ok
+  id<NSObject, NSCopying> anQualId2 = aBlock; // Ok
+  id<NSObject, NSCopying, NSObject, NSCopying> anQualId3 = aBlock; // Ok
+  id <P1>  anQualId4  = aBlock; // expected-error {{initializing 'id<P1>' with an expression of incompatible type 'void (^)()'}}
+  id<NSObject, P1, NSCopying> anQualId5 = aBlock; // expected-error {{initializing 'id<NSObject,P1,NSCopying>' with an expression of incompatible type 'void (^)()'}}
+  id<NSCopying> anQualId6 = aBlock; // Ok
+}
+
+void Test3() {
+  void (^aBlock)();
+  NSObject *NSO = aBlock; // Ok
+  NSObject<NSObject> *NSO1 = aBlock; // Ok
+  NSObject<NSObject, NSCopying> *NSO2 = aBlock; // Ok
+  NSObject<NSObject, NSCopying, NSObject, NSCopying> *NSO3 = aBlock; // Ok
+  NSObject <P1>  *NSO4  = aBlock; // expected-error {{initializing 'NSObject<P1> *' with an expression of incompatible type 'void (^)()'}}
+  NSObject<NSObject, P1, NSCopying> *NSO5 = aBlock; // expected-error {{initializing 'NSObject<NSObject,P1,NSCopying> *' with an expression of incompatible type 'void (^)()'}}
+  NSObject<NSCopying> *NSO6 = aBlock; // Ok
+}
diff --git a/test/SemaObjC/class-unavail-warning.m b/test/SemaObjC/class-unavail-warning.m
index a337c97..3ebf3e7 100644
--- a/test/SemaObjC/class-unavail-warning.m
+++ b/test/SemaObjC/class-unavail-warning.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -fsyntax-only -verify %s
+// RUN: %clang_cc1  -fsyntax-only  -triple x86_64-apple-darwin10 -verify %s
 // rdar://9092208
 
 __attribute__((unavailable("not available")))
@@ -15,7 +15,7 @@
 
 @end
 
-@interface Foo {
+@interface Gorf {
   MyClass *ivar; // expected-error {{unavailable}}
 }
 - (MyClass *)meth; // expected-error {{unavailable}}
@@ -40,3 +40,30 @@
 
  return 0;
 }
+
+// rdar://16681279
+@interface NSObject @end
+
+__attribute__((visibility("default"))) __attribute__((availability(macosx,unavailable)))
+@interface Foo : NSObject @end // expected-note 3 {{'Foo' has been explicitly marked unavailable here}}
+@interface AppDelegate  : NSObject
+@end
+
+@class Foo;
+
+@implementation AppDelegate
+- (void) applicationDidFinishLaunching
+{
+  Foo *foo = 0; // expected-error {{'Foo' is unavailable}}
+}
+@end
+
+@class Foo;
+Foo *g_foo = 0; // expected-error {{'Foo' is unavailable}}
+
+@class Foo;
+@class Foo;
+@class Foo;
+Foo * f_func() { // expected-error {{'Foo' is unavailable}}
+  return 0; 
+}
diff --git a/test/SemaObjC/comptypes-legal.m b/test/SemaObjC/comptypes-legal.m
index d83d559..05f1897 100644
--- a/test/SemaObjC/comptypes-legal.m
+++ b/test/SemaObjC/comptypes-legal.m
@@ -35,3 +35,20 @@
   // Since registerFunc: expects a Derived object as it's second argument, I don't know why this would be legal.
   [Derived registerFunc: ExternFunc];  // expected-warning{{incompatible pointer types sending 'NSObject *(NSObject *, NSObject *)' to parameter of type 'FuncSignature *'}}
 }
+
+// rdar://10751015
+@protocol NSCopying @end
+@interface I
+- (void) Meth : (id <NSCopying>)aKey; // expected-note {{passing argument to parameter 'aKey' here}}
+@end
+
+@class ForwarClass; // expected-note 3 {{conformance of forward class ForwarClass to protocol NSCopying can not be confirmed}}
+
+ForwarClass *Test10751015 (I* pi, ForwarClass *ns_forward) {
+
+  [pi Meth : ns_forward ]; // expected-warning {{sending 'ForwarClass *' to parameter of incompatible type 'id<NSCopying>'}}
+
+  id <NSCopying> id_ns = ns_forward; // expected-warning {{initializing 'id<NSCopying>' with an expression of incompatible type 'ForwarClass *'}}
+
+  return id_ns; // expected-warning {{returning 'id<NSCopying>' from a function with incompatible result type 'ForwarClass *'}}
+}
diff --git a/test/SemaObjC/deprecate_function_containers.m b/test/SemaObjC/deprecate_function_containers.m
new file mode 100644
index 0000000..531cf11
--- /dev/null
+++ b/test/SemaObjC/deprecate_function_containers.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1  -fsyntax-only -fblocks -verify -Wno-objc-root-class %s
+// rdar://10414277
+
+@protocol P
+void p_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}}
+@end
+
+@interface I
+void foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}}
+inline void v_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}}
+static int s_foo() {return 0; } // expected-warning {{function definition inside an Objective-C container is deprecated}}
+static inline int si_val() { return 1; } // expected-warning {{function definition inside an Objective-C container is deprecated}}
+@end
+
+@interface I(CAT)
+void cat_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}}
+@end
+
+@implementation I
+inline void v_imp_foo() {} 
+@end
+
+@implementation I(CAT)
+void cat_imp_foo() {} 
+@end
+
+// rdar://16859666
+@interface PrototypeState
+
+@property (strong, readwrite) id moin1; // expected-note {{property declared here}}
+
+static inline void prototype_observe_moin1(void (^callback)(id)) { // expected-warning {{function definition inside an Objective-C container is deprecated}}
+        (void)^(PrototypeState *prototypeState){
+            callback(prototypeState.moin1); // expected-error {{use of Objective-C property in function nested in Objective-C container not supported, move function outside its container}}
+        };
+}
+@end
diff --git a/test/SemaObjC/iboutlet.m b/test/SemaObjC/iboutlet.m
index 3c7f958..63eac9a 100644
--- a/test/SemaObjC/iboutlet.m
+++ b/test/SemaObjC/iboutlet.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s
-// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Wno-objc-root-class -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
 // rdar://11448209
 
 #define READONLY readonly
@@ -40,3 +40,15 @@
 @implementation RKTFHView
 @synthesize synthReadOnlyReadWrite=_synthReadOnlyReadWrite;
 @end
+
+// rdar://15885642
+@interface WeakOutlet 
+@property IBOutlet __weak WeakOutlet* WeakProp;
+@end
+
+WeakOutlet* func() {
+  __weak WeakOutlet* pwi;
+  pwi.WeakProp = (WeakOutlet*)0;
+  pwi.WeakProp = pwi.WeakProp;
+  return pwi.WeakProp;
+}
diff --git a/test/SemaObjC/ns_returns_retained_block_return.m b/test/SemaObjC/ns_returns_retained_block_return.m
new file mode 100644
index 0000000..e5a96ca
--- /dev/null
+++ b/test/SemaObjC/ns_returns_retained_block_return.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1  -fblocks -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1  -fblocks -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
+// rdar://17259812
+
+typedef void (^BT) ();
+
+BT foo()  __attribute__((ns_returns_retained));
+
+@interface I
+BT foo()  __attribute__((ns_returns_retained));
+- (BT) Meth __attribute__((ns_returns_retained));
++ (BT) ClsMeth __attribute__((ns_returns_retained));
+@end
+
+@implementation I
+BT foo()  __attribute__((ns_returns_retained)) {return ^{}; }
+- (BT) Meth {return ^{}; }
++ (BT) ClsMeth {return ^{}; }
+@end
diff --git a/test/SemaObjC/objc-container-subscripting-attr.m b/test/SemaObjC/objc-container-subscripting-attr.m
new file mode 100644
index 0000000..17110c4
--- /dev/null
+++ b/test/SemaObjC/objc-container-subscripting-attr.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://16842487
+// pr19682
+
+@interface Subscriptable
+- (id)objectForKeyedSubscript:(id)sub __attribute__((unavailable)); // expected-note 2 {{'objectForKeyedSubscript:' has been explicitly marked unavailable here}}
+- (void)setObject:(id)object forKeyedSubscript:(id)key __attribute__((unavailable)); // expected-note {{'setObject:forKeyedSubscript:' has been explicitly marked unavailable here}}
+@end
+
+id test(Subscriptable *obj) {
+  obj[obj] = obj;  // expected-error {{'setObject:forKeyedSubscript:' is unavailable}}
+  return obj[obj]; // expected-error {{'objectForKeyedSubscript:' is unavailable}}
+}
+
+id control(Subscriptable *obj) {
+  return [obj objectForKeyedSubscript:obj]; // expected-error {{'objectForKeyedSubscript:' is unavailable}}
+}
+
diff --git a/test/SemaObjC/objc-literal-nsnumber.m b/test/SemaObjC/objc-literal-nsnumber.m
index 26bca18..a2d3728 100644
--- a/test/SemaObjC/objc-literal-nsnumber.m
+++ b/test/SemaObjC/objc-literal-nsnumber.m
@@ -1,10 +1,12 @@
-// RUN: %clang_cc1  -fsyntax-only -fblocks -verify %s
+// RUN: %clang_cc1  -fsyntax-only -fblocks -triple x86_64-apple-darwin10 -verify %s
 // rdar://10111397
 
 #if __LP64__
 typedef unsigned long NSUInteger;
+typedef long NSInteger;
 #else
 typedef unsigned int NSUInteger;
+typedef int NSInteger;
 #endif
 
 @interface NSObject
@@ -13,10 +15,23 @@
 
 @interface NSNumber : NSObject
 + (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
 + (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
 + (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithInteger:(NSInteger)value ;
++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ;
 @end
 
+// rdar://16417427
+int big = 1391126400;
+int thousand = 1000;
 int main() {
   NSNumber * N = @3.1415926535;  // expected-error {{declaration of 'numberWithDouble:' is missing in NSNumber class}}
   NSNumber *noNumber = @__objc_yes; // expected-error {{declaration of 'numberWithBool:' is missing in NSNumber class}}
@@ -32,6 +47,9 @@
   int five = 5;
   @-five; // expected-error{{@- must be followed by a number to form an NSNumber object}}
   @+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}}
+  NSNumber *av = @(1391126400000);
+  NSNumber *bv = @(1391126400 * 1000); // expected-warning {{overflow in expression; result is -443003904 with type 'int'}}
+  NSNumber *cv = @(big * thousand);
 }
 
 // Dictionary test
diff --git a/test/SemaObjC/objc-mixed-bridge-attribute.m b/test/SemaObjC/objc-mixed-bridge-attribute.m
new file mode 100644
index 0000000..83fb4d3
--- /dev/null
+++ b/test/SemaObjC/objc-mixed-bridge-attribute.m
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
+// rdar://17238954
+
+typedef const struct __attribute__((objc_bridge(NSAttributedString))) __CFAttributedString *CFAttributedStringRef;
+
+typedef struct __attribute__((objc_bridge_mutable(NSMutableAttributedString))) __CFAttributedString *CFMutableAttributedStringRef;
+
+@interface NSAttributedString
+@end
+
+@interface NSMutableAttributedString
+@end
+
+struct __CFAttributedString {
+};
+
+void Test1(CFAttributedStringRef attrStr, CFMutableAttributedStringRef mutable_attrStr)
+{
+  id x = (NSAttributedString *) attrStr;
+  id x1 =(NSAttributedString *) mutable_attrStr;
+  id x2 = (NSMutableAttributedString *) attrStr;
+  id x3 = (NSMutableAttributedString *) mutable_attrStr;
+}
+
+void Test2(NSAttributedString *ns_attrStr, NSMutableAttributedString *ns_mutable_attr_Str) {
+  CFAttributedStringRef cfsr = (CFAttributedStringRef) ns_attrStr;
+  CFMutableAttributedStringRef cfsr1 = (CFMutableAttributedStringRef) ns_attrStr;
+  CFAttributedStringRef cfsr2 = (CFAttributedStringRef) ns_mutable_attr_Str;
+  CFMutableAttributedStringRef cfsr3 = (CFMutableAttributedStringRef) ns_mutable_attr_Str;
+}
+
+// Tests with no definition declaration for struct __NDCFAttributedString.
+typedef const struct __attribute__((objc_bridge(NSAttributedString))) __NDCFAttributedString *NDCFAttributedStringRef;
+
+typedef struct __attribute__((objc_bridge_mutable(NSMutableAttributedString))) __NDCFAttributedString *NDCFMutableAttributedStringRef;
+
+void Test3(NDCFAttributedStringRef attrStr, NDCFMutableAttributedStringRef mutable_attrStr)
+{
+  id x = (NSAttributedString *) attrStr;
+  id x1 =(NSAttributedString *) mutable_attrStr;
+  id x2 = (NSMutableAttributedString *) attrStr;
+  id x3 = (NSMutableAttributedString *) mutable_attrStr;
+}
+
+void Test4(NSAttributedString *ns_attrStr, NSMutableAttributedString *ns_mutable_attr_Str) {
+  NDCFAttributedStringRef cfsr = (NDCFAttributedStringRef) ns_attrStr;
+  NDCFMutableAttributedStringRef cfsr1 = (NDCFMutableAttributedStringRef) ns_attrStr;
+  NDCFAttributedStringRef cfsr2 = (NDCFAttributedStringRef) ns_mutable_attr_Str;
+  NDCFMutableAttributedStringRef cfsr3 = (NDCFMutableAttributedStringRef) ns_mutable_attr_Str;
+}
diff --git a/test/SemaObjC/property-deprecated-warning.m b/test/SemaObjC/property-deprecated-warning.m
index c89edb9..4beb23a 100644
--- a/test/SemaObjC/property-deprecated-warning.m
+++ b/test/SemaObjC/property-deprecated-warning.m
@@ -78,3 +78,28 @@
     return [obj ptarget];  // no-warning
   return [obj2 ptarget];   // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
 }
+
+// rdar://15951801
+@interface Foo
+{
+  int _x;
+}
+@property(nonatomic,readonly) int x;
+- (void)setX:(int)x __attribute__ ((deprecated)); // expected-note 2 {{'setX:' has been explicitly marked deprecated here}}
+- (int)x __attribute__ ((unavailable)); // expected-note {{'x' has been explicitly marked unavailable here}}
+@end
+
+@implementation Foo
+- (void)setX:(int)x {
+	_x = x;
+}
+- (int)x {
+  return _x;
+}
+@end
+
+void testUserAccessorAttributes(Foo *foo) {
+        [foo setX:5678]; // expected-warning {{'setX:' is deprecated}}
+	foo.x = foo.x; // expected-error {{property access is using 'x' method which is unavailable}} \
+		       // expected-warning {{property access is using 'setX:' method which is deprecated}}
+}
diff --git a/test/SemaObjC/selector-1.m b/test/SemaObjC/selector-1.m
index 0d83d47..4efa0d7 100644
--- a/test/SemaObjC/selector-1.m
+++ b/test/SemaObjC/selector-1.m
@@ -14,6 +14,18 @@
 	return @selector(compare:);	// expected-warning {{several methods with selector 'compare:' of mismatched types are found for the @selector expression}}
 }
 
+// rdar://16458579
+void Test16458579() {
+ SEL s = @selector((retain));
+ SEL s1 = @selector((meth1:));
+ SEL s2 = @selector((retainArgument::));
+ SEL s3 = @selector((retainArgument:::::));
+ SEL s4 = @selector((retainArgument:with:));
+ SEL s5 = @selector((meth1:with:with:));
+ SEL s6 = @selector((getEnum:enum:bool:));
+ SEL s7 = @selector((char:float:double:unsigned:short:long:));
+ SEL s9 = @selector((:enum:bool:));
+}
 int main() {
  SEL s = @selector(retain);
  SEL s1 = @selector(meth1:);
diff --git a/test/SemaObjC/warn-retain-cycle.m b/test/SemaObjC/warn-retain-cycle.m
index eb4e966..4398d29 100644
--- a/test/SemaObjC/warn-retain-cycle.m
+++ b/test/SemaObjC/warn-retain-cycle.m
@@ -122,8 +122,8 @@
   // Sanity check that we are really whitelisting 'addOperationWithBlock:' and not doing
   // something funny.
   [myOperationQueue addSomethingElse:^() { // expected-note {{block will be retained by an object strongly retained by the captured object}}
-    if (count > 20) { // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}}
-      doSomething(count);
+    if (count > 20) {
+      doSomething(count); // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}}
     }
   }];
 }
@@ -184,3 +184,17 @@
   })];
 }
 
+// rdar://16944538
+void func(int someCondition) {
+
+__block void(^myBlock)(void) = ^{
+        if (someCondition) {
+            doSomething(1);
+            myBlock();
+        }
+        else {
+	    myBlock = ((void*)0);
+        }
+   };
+
+}
diff --git a/test/SemaObjCXX/instantiate-property-access.mm b/test/SemaObjCXX/instantiate-property-access.mm
new file mode 100644
index 0000000..8d5c201
--- /dev/null
+++ b/test/SemaObjCXX/instantiate-property-access.mm
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+class C {};
+bool operator == (C c1, C c2);
+
+bool operator == (C c1, int i);
+bool operator == (int i, C c2);
+
+C operator += (C c1, C c2);
+
+enum TextureType { TextureType3D  };
+
+@interface Texture
+@property  int textureType;
+@property  C c;
+@end
+
+template <typename> class Framebuffer {
+public:
+  Texture **color_attachment;  
+  Framebuffer();
+};
+
+template <typename T> Framebuffer<T>::Framebuffer() {
+  (void)(color_attachment[0].textureType == TextureType3D);
+  color_attachment[0].textureType += 1;
+  (void)(color_attachment[0].c == color_attachment[0].c);
+  (void)(color_attachment[0].c == 1);
+  (void)(1 == color_attachment[0].c);
+}
+
+void foo() {
+  Framebuffer<int>();
+}
diff --git a/test/SemaTemplate/dependent-names.cpp b/test/SemaTemplate/dependent-names.cpp
index 5a25030..011e073 100644
--- a/test/SemaTemplate/dependent-names.cpp
+++ b/test/SemaTemplate/dependent-names.cpp
@@ -399,3 +399,18 @@
 using size_t = decltype(sizeof(0));
 void *operator new(size_t, OperatorNew::X); // expected-note-re {{should be declared prior to the call site{{$}}}}
 template void OperatorNew::f(OperatorNew::X); // expected-note {{instantiation of}}
+
+namespace PR19936 {
+  template<typename T> decltype(*T()) f() {} // expected-note {{previous}}
+  template<typename T> decltype(T() * T()) g() {} // expected-note {{previous}}
+
+  // Create some overloaded operators so we build an overload operator call
+  // instead of a builtin operator call for the dependent expression.
+  enum E {};
+  int operator*(E);
+  int operator*(E, E);
+
+  // Check that they still profile the same.
+  template<typename T> decltype(*T()) f() {} // expected-error {{redefinition}}
+  template<typename T> decltype(T() * T()) g() {} // expected-error {{redefinition}}
+}
diff --git a/test/SemaTemplate/instantiate-default-assignment-operator.cpp b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
index 31cdef5..6794671 100644
--- a/test/SemaTemplate/instantiate-default-assignment-operator.cpp
+++ b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
@@ -13,5 +13,5 @@
   a1 = a2;
 
   B b1, b2;
-  b1 = b2; 
+  b1 = b2;
 }
diff --git a/test/SemaTemplate/ms-delayed-default-template-args.cpp b/test/SemaTemplate/ms-delayed-default-template-args.cpp
new file mode 100644
index 0000000..ca9ddb0
--- /dev/null
+++ b/test/SemaTemplate/ms-delayed-default-template-args.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -fms-compatibility -std=c++11 %s -verify
+
+// MSVC should compile this file without errors.
+
+namespace test_basic {
+template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+struct Foo { T x; };
+typedef int Baz;
+template struct Foo<>;
+}
+
+namespace test_namespace {
+namespace nested {
+template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+struct Foo {
+  static_assert(sizeof(T) == 4, "should get int, not double");
+};
+typedef int Baz;
+}
+typedef double Baz;
+template struct nested::Foo<>;
+}
+
+namespace test_inner_class_template {
+struct Outer {
+  template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+  struct Foo {
+    static_assert(sizeof(T) == 4, "should get int, not double");
+  };
+  typedef int Baz;
+};
+typedef double Baz;
+template struct Outer::Foo<>;
+}
+
+namespace test_nontype_param {
+template <typename T> struct Bar { T x; };
+typedef int Qux;
+template <Bar<Qux> *P>
+struct Foo {
+};
+Bar<int> g;
+template struct Foo<&g>;
+}
+
+// MSVC accepts this, but Clang doesn't.
+namespace test_template_instantiation_arg {
+template <typename T> struct Bar { T x; };
+template <typename T = Bar<Weber>>  // expected-error {{use of undeclared identifier 'Weber'}}
+struct Foo {
+  static_assert(sizeof(T) == 4, "Bar should have gotten int");
+  // FIXME: These diagnostics are bad.
+}; // expected-error {{expected ',' or '>' in template-parameter-list}}
+// expected-warning@-1 {{does not declare anything}}
+typedef int Weber;
+}
+
+#ifdef __clang__
+// These are negative test cases that MSVC doesn't compile either.  Try to use
+// unique undeclared identifiers so typo correction doesn't find types declared
+// above.
+
+namespace test_undeclared_nontype_parm_type {
+template <Zargon N> // expected-error {{unknown type name 'Zargon'}}
+struct Foo { int x[N]; };
+typedef int Zargon;
+template struct Foo<4>;
+}
+
+namespace test_undeclared_nontype_parm_type_no_name {
+template <typename T, Asdf> // expected-error {{unknown type name 'Asdf'}}
+struct Foo { T x; };
+template struct Foo<int, 0>;
+}
+
+namespace test_undeclared_type_arg {
+template <typename T>
+struct Foo { T x; };
+template struct Foo<Yodel>; // expected-error {{use of undeclared identifier 'Yodel'}}
+}
+
+namespace test_undeclared_nontype_parm_arg {
+// Bury an undeclared type as a template argument to the type of a non-type
+// template parameter.
+template <typename T> struct Bar { T x; };
+
+template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}}
+// expected-note@-1 {{template parameter is declared here}}
+struct Foo { };
+
+typedef int Xylophone;
+Bar<Xylophone> g;
+template struct Foo<&g>; // expected-error {{cannot be converted}}
+}
+
+#endif
diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 8f9653d..40f73c0 100644
--- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
 
 
 template <class T>
@@ -64,7 +64,7 @@
 class B : public A<T> {
 public:
   void f() {
-    var = 3;
+    var = 3; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
   }
 };
 
@@ -160,7 +160,7 @@
 class A : public T {
 public:
   void f(int hWnd) {
-    m_hWnd = 1;
+    m_hWnd = 1; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}}
   }
 };
 
@@ -204,18 +204,20 @@
   static int sa;
 };
 template <typename T> struct B : T {
-  int     foo() { return a; }
-  int    *bar() { return &a; }
+  int     foo() { return a; }           // expected-warning {{lookup into dependent bases}}
+  int    *bar() { return &a; }          // expected-warning {{lookup into dependent bases}}
   int     baz() { return T::a; }
   int T::*qux() { return &T::a; }
   static int T::*stuff() { return &T::a; }
   static int stuff1() { return T::sa; }
   static int *stuff2() { return &T::sa; }
+  static int stuff3() { return sa; }    // expected-warning {{lookup into dependent bases}}
+  static int *stuff4() { return &sa; }  // expected-warning {{lookup into dependent bases}}
 };
 
 template <typename T> struct C : T {
-  int     foo() { return b; }      // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}}
-  int    *bar() { return &b; }     // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}}
+  int     foo() { return b; }      // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
+  int    *bar() { return &b; }     // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
   int     baz() { return T::b; }   // expected-error {{no member named 'b' in 'PR16014::A'}}
   int T::*qux() { return &T::b; }  // expected-error {{no member named 'b' in 'PR16014::A'}}
   int T::*fuz() { return &U::a; }  // expected-error {{use of undeclared identifier 'U'}}
@@ -259,3 +261,202 @@
 template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
 
 }
+
+namespace nonmethod_missing_this {
+template <typename T> struct Base { int y = 42; };
+template <typename T> struct Derived : Base<T> {
+  int x = y; // expected-warning {{lookup into dependent bases}}
+  auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
+    return y * j; // expected-warning {{lookup into dependent bases}}
+  }
+  int bar() {
+    return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}
+  }
+};
+template struct Derived<int>;
+}
+
+namespace typedef_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == 4, "");
+}
+
+namespace struct_in_base {
+template <typename T> struct A { struct NameFromBase {}; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == 1, "");
+}
+
+namespace enum_in_base {
+template <typename T> struct A { enum NameFromBase { X }; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
+}
+
+namespace two_types_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B { struct NameFromBase { T m; }; };
+template <typename T> struct C : A<T>, B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+static_assert(sizeof(C<int>) == 4, "");
+}
+
+namespace type_and_decl_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B { static const T NameFromBase = 42; };
+template <typename T> struct C : A<T>, B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+}
+
+namespace classify_type_from_base {
+template <typename T> struct A { struct NameFromBase {}; };
+template <typename T> struct B : A<T> {
+  A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+}
+
+namespace classify_nontype_from_base {
+// MSVC does not do lookup of non-type declarations from dependent template base
+// classes.  The extra lookup only applies to types.
+template <typename T> struct A { void NameFromBase() {} };
+template <void (*F)()> struct B { };
+template <typename T> struct C : A<T> {
+  B<C::NameFromBase> a; // correct
+  B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
+};
+}
+
+namespace template_in_base {
+template <typename T> struct A {
+  template <typename U> struct NameFromBase { U x; };
+};
+template <typename T> struct B : A<T> {
+  // Correct form.
+  typename B::template NameFromBase<T> m;
+};
+template <typename T> struct C : A<T> {
+  // Incorrect form.
+  NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}}
+  //expected-error@-1 {{expected member name or ';' after declaration specifiers}}
+};
+}
+
+namespace type_in_inner_class_in_base {
+template <typename T>
+struct A {
+  struct B { typedef T NameFromBase; };
+};
+template <typename T>
+struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+}
+
+namespace type_in_inner_template_class_in_base {
+template <typename T>
+struct A {
+  template <typename U> struct B { typedef U InnerType; };
+};
+template <typename T>
+struct C : A<T>::template B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+}
+
+namespace have_nondependent_base {
+template <typename T>
+struct A {
+  // Nothing, lookup should fail.
+};
+template <typename T>
+struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+}
+
+namespace type_in_base_of_dependent_base {
+struct A { typedef int NameFromBase; };
+template <typename T>
+struct B : A {};
+// FIXME: MSVC accepts this.
+template <typename T>
+struct C : B<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+}
+
+namespace lookup_in_function_contexts {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T>
+struct B : A<T> {
+  // expected-warning@+1 {{lookup into dependent bases}}
+  static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
+    return {};
+  }
+
+  static void memberFunc() {
+    NameFromBase x; // expected-warning {{lookup into dependent bases}}
+  }
+
+  static void funcLocalClass() {
+    struct X {
+      NameFromBase x; // expected-warning {{lookup into dependent bases}}
+    } y;
+  }
+
+  void localClassMethod() {
+    struct X {
+      void bar() {
+        NameFromBase m; // expected-warning {{lookup into dependent bases}}
+      }
+    } x;
+    x.bar();
+  }
+
+  static void funcLambda() {
+    auto l = []() {
+      NameFromBase x; // expected-warning {{lookup into dependent bases}}
+    };
+    l();
+  }
+
+  static constexpr int constexprFunc() {
+    NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
+    return sizeof(x);
+  }
+
+  static auto autoFunc() {
+    NameFromBase x; // expected-warning {{lookup into dependent bases}}
+    return x;
+  }
+};
+
+// Force us to parse the methods.
+template struct B<int>;
+}
+
+namespace function_template_deduction {
+// Overloaded function templates.
+template <int N> int f() { return N; }
+template <typename T> int f() { return sizeof(T); }
+
+// Dependent base class with type.
+template <typename T>
+struct A { typedef T NameFromBase; };
+template <typename T>
+struct B : A<T> {
+  // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
+  int x = f<NameFromBase>();
+};
+
+// Dependent base class with enum.
+template <typename T> struct C { enum { NameFromBase = 4 }; };
+template <typename T> struct D : C<T> {
+  // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
+  int x = f<NameFromBase>();
+};
+}
diff --git a/test/SemaTemplate/ms-sizeof-missing-typename.cpp b/test/SemaTemplate/ms-sizeof-missing-typename.cpp
new file mode 100644
index 0000000..ff8984f
--- /dev/null
+++ b/test/SemaTemplate/ms-sizeof-missing-typename.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -verify %s
+
+// If we were even more clever, we'd tell the user to use one set of parens to
+// get the size of this type, so they don't get errors after inserting typename.
+
+namespace basic {
+template <typename T> int type_f() { return sizeof T::type; }  // expected-error {{missing 'typename' prior to dependent type name 'X::type'}}
+template <typename T> int type_g() { return sizeof(T::type); }  // expected-warning {{missing 'typename' prior to dependent type name 'X::type'}}
+template <typename T> int type_h() { return sizeof((T::type)); }  // expected-error {{missing 'typename' prior to dependent type name 'X::type'}}
+template <typename T> int value_f() { return sizeof T::not_a_type; }
+template <typename T> int value_g() { return sizeof(T::not_a_type); }
+template <typename T> int value_h() { return sizeof((T::not_a_type)); }
+struct X {
+  typedef int type;
+  static const int not_a_type;
+};
+int bar() {
+  return
+      type_f<X>() + // expected-note-re {{in instantiation {{.*}} requested here}}
+      type_g<X>() + // expected-note-re {{in instantiation {{.*}} requested here}}
+      type_h<X>() + // expected-note-re {{in instantiation {{.*}} requested here}}
+      value_f<X>() +
+      value_f<X>() +
+      value_f<X>();
+}
+}
+
+namespace nested_sizeof {
+template <typename T>
+struct Foo {
+  enum {
+    // expected-warning@+2 {{use 'template' keyword to treat 'InnerTemplate' as a dependent template name}}
+    // expected-warning@+1 {{missing 'typename' prior to dependent type name 'Bar::InnerType'}}
+    x1 = sizeof(typename T::/*template*/ InnerTemplate<sizeof(/*typename*/ T::InnerType)>),
+    // expected-warning@+1 {{missing 'typename' prior to dependent type name 'Bar::InnerType'}}
+    x2 = sizeof(typename T::template InnerTemplate<sizeof(/*typename*/ T::InnerType)>),
+    // expected-warning@+1 {{use 'template' keyword to treat 'InnerTemplate' as a dependent template name}}
+    y1 = sizeof(typename T::/*template*/ InnerTemplate<sizeof(T::InnerVar)>),
+    y2 = sizeof(typename T::template InnerTemplate<sizeof(T::InnerVar)>),
+    z = sizeof(T::template InnerTemplate<sizeof(T::InnerVar)>::x),
+  };
+};
+struct Bar {
+  template <int N>
+  struct InnerTemplate { int x[N]; };
+  typedef double InnerType;
+  static const int InnerVar = 42;
+};
+template struct Foo<Bar>; // expected-note-re {{in instantiation {{.*}} requested here}}
+}
+
+namespace ambiguous_missing_parens {
+// expected-error@+1 {{'Q::U' instantiated to a class template, not a function template}}
+template <typename T> void f() { int a = sizeof T::template U<0> + 4; }
+struct Q {
+  // expected-error@+1 {{class template declared here}}
+  template <int> struct U {};
+};
+// expected-note-re@+1 {{in instantiation {{.*}} requested here}}
+template void f<Q>();
+}
diff --git a/test/SemaTemplate/pack-deduction.cpp b/test/SemaTemplate/pack-deduction.cpp
new file mode 100644
index 0000000..f3f969e
--- /dev/null
+++ b/test/SemaTemplate/pack-deduction.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<typename ...T> struct X {};
+
+template<typename T, typename U> struct P {};
+
+namespace Nested {
+  template<typename ...T> int f1(X<T, T...>... a); // expected-note +{{conflicting types for parameter 'T'}}
+  template<typename ...T> int f2(P<X<T...>, T> ...a); // expected-note +{{conflicting types for parameter 'T'}}
+
+  int a1 = f1(X<int, int, double>(), X<double, int, double>());
+  int a2 = f1(X<int, int>());
+  int a3 = f1(X<int>(), X<double>()); // expected-error {{no matching}}
+  int a4 = f1(X<int, int>(), X<int>()); // expected-error {{no matching}}
+  int a5 = f1(X<int>(), X<int, int>()); // expected-error {{no matching}}
+  int a6 = f1(X<int, int, int>(), X<int, int, int>(), X<int, int, int, int>()); // expected-error {{no matching}}
+
+  int b1 = f2(P<X<int, double>, int>(), P<X<int, double>, double>());
+  int b2 = f2(P<X<int, double>, int>(), P<X<int, double>, double>(), P<X<int, double>, char>()); // expected-error {{no matching}}
+}
+
+namespace PR14841 {
+  template<typename T, typename U> struct A {};
+  template<typename ...Ts> void f(A<Ts...>); // expected-note {{substitution failure [with Ts = <char, short, int>]: too many template arg}}
+
+  void g(A<char, short> a) {
+    f(a);
+    f<char>(a);
+    f<char, short>(a);
+    f<char, short, int>(a); // expected-error {{no matching function}}
+  }
+}
+
+namespace RetainExprPacks {
+  int f(int a, int b, int c);
+  template<typename ...Ts> struct X {};
+  template<typename ...Ts> int g(X<Ts...>, decltype(f(Ts()...)));
+  int n = g<int, int>(X<int, int, int>(), 0);
+}
diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp
index 6bd567f6..602e903 100644
--- a/test/SemaTemplate/typename-specifier.cpp
+++ b/test/SemaTemplate/typename-specifier.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unused
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unused -fms-compatibility -DMSVC
 namespace N {
   struct A {
     typedef int type;
@@ -136,19 +137,106 @@
   };
 
   void foo() {
-    pair<ExampleItemSet::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#ifdef MSVC
+    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+    // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#endif
+    pair<ExampleItemSet::iterator, int> i;
     pair<this->ExampleItemSet::iterator, int> i; // expected-error-re {{template argument for template type parameter must be a type{{$}}}}
     pair<ExampleItemSet::operator[], int> i; // expected-error-re {{template argument for template type parameter must be a type{{$}}}}
   }
-  pair<ExampleItemSet::iterator, int> elt; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#ifdef MSVC
+    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+  // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#endif
+  pair<ExampleItemSet::iterator, int> elt;
 
 
   typedef map<int, ExampleItem*> ExampleItemMap;
 
   static void bar() {
-    pair<ExampleItemMap::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#ifdef MSVC
+    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+    // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#endif
+    pair<ExampleItemMap::iterator, int> i;
   }
-  pair<ExampleItemMap::iterator, int> entry; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#ifdef MSVC
+    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+  // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#endif
+  pair<ExampleItemMap::iterator, int> entry;
   pair<bar, int> foobar; // expected-error {{template argument for template type parameter must be a type}}
 };
 } // namespace missing_typename
+
+namespace missing_typename_and_base {
+template <class T> struct Bar {}; // expected-note 1+ {{template parameter is declared here}}
+template <typename T>
+struct Foo : T {
+
+  // FIXME: MSVC accepts this code.
+  Bar<TypeInBase> x; // expected-error {{use of undeclared identifier 'TypeInBase'}}
+
+#ifdef MSVC
+  // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+  // expected-error@+2 {{must be a type; did you forget 'typename'?}}
+#endif
+  Bar<T::TypeInBase> y;
+
+#ifdef MSVC
+  // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+  // expected-error@+2 {{must be a type; did you forget 'typename'?}}
+#endif
+  Bar<T::NestedRD::TypeInNestedRD> z;
+
+};
+struct Base {
+  typedef int TypeInBase;
+  struct NestedRD {
+    typedef int TypeInNestedRD;
+  };
+};
+Foo<Base> x;
+} // namespace missing_typename_and_base
+
+namespace func_type_vs_construct_tmp {
+template <typename> struct S { typedef int type; };
+template <typename T> void f();
+template <int N> void f();
+
+// expected-error@+1 {{missing 'typename' prior to dependent type name 'S<int>::type'}}
+template <typename T> void g() { f</*typename*/ S<T>::type(int())>(); }
+
+// Adding typename does fix the diagnostic.
+template <typename T> void h() { f<typename S<T>::type(int())>(); }
+
+void j() {
+  g<int>(); // expected-note-re {{in instantiation {{.*}} requested here}}
+  h<int>();
+}
+} // namespace func_type_vs_construct_tmp
+
+namespace pointer_vs_multiply {
+int x;
+// expected-error@+1 {{missing 'typename' prior to dependent type name 'B::type_or_int'}}
+template <typename T> void g() { T::type_or_int * x; }
+// expected-error@+1 {{typename specifier refers to non-type member 'type_or_int' in 'pointer_vs_multiply::A'}}
+template <typename T> void h() { typename T::type_or_int * x; }
+
+struct A { static const int type_or_int = 5; }; // expected-note {{referenced member 'type_or_int' is declared here}}
+struct B { typedef int type_or_int; };
+
+void j() {
+  g<A>();
+  g<B>(); // expected-note-re {{in instantiation {{.*}} requested here}}
+  h<A>(); // expected-note-re {{in instantiation {{.*}} requested here}}
+  h<B>();
+}
+} // namespace pointer_vs_multiply
diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg
index 01b54c7..4fa6e78 100644
--- a/test/Unit/lit.cfg
+++ b/test/Unit/lit.cfg
@@ -100,5 +100,9 @@
     lit_config.fatal('No LLVM libs dir set!')
 shlibpath = os.path.pathsep.join((llvm_libs_dir,
                                  config.environment.get(shlibpath_var,'')))
-config.environment[shlibpath_var] = shlibpath
 
+# Win32 seeks DLLs along %PATH%.
+if sys.platform in ['win32', 'cygwin'] and os.path.isdir(config.shlibdir):
+    shlibpath = os.path.pathsep.join((config.shlibdir, shlibpath))
+
+config.environment[shlibpath_var] = shlibpath
diff --git a/test/VFS/Inputs/Incomplete.h b/test/VFS/Inputs/Incomplete.h
new file mode 100644
index 0000000..29fafc3
--- /dev/null
+++ b/test/VFS/Inputs/Incomplete.h
@@ -0,0 +1 @@
+// does not include IncompleteVFS.h or IncompleteReal.h
diff --git a/test/VFS/Inputs/IncompleteVFS.h b/test/VFS/Inputs/IncompleteVFS.h
new file mode 100644
index 0000000..22cfe7d
--- /dev/null
+++ b/test/VFS/Inputs/IncompleteVFS.h
@@ -0,0 +1 @@
+// IncompleteVFS.h
diff --git a/test/VFS/Inputs/incomplete-umbrella.modulemap b/test/VFS/Inputs/incomplete-umbrella.modulemap
new file mode 100644
index 0000000..5afac92
--- /dev/null
+++ b/test/VFS/Inputs/incomplete-umbrella.modulemap
@@ -0,0 +1,5 @@
+framework module Incomplete {
+  umbrella header "Incomplete.h"
+  export *
+  module * { export * }
+}
diff --git a/test/VFS/Inputs/vfsoverlay.yaml b/test/VFS/Inputs/vfsoverlay.yaml
index 0aa8cd6..f395d45 100644
--- a/test/VFS/Inputs/vfsoverlay.yaml
+++ b/test/VFS/Inputs/vfsoverlay.yaml
@@ -29,6 +29,23 @@
         },
         { 'name': 'Foo.framework/Headers/Foo.h', 'type': 'file',
           'external-contents': 'INPUT_DIR/Foo.h'
+        },
+        { 'name': 'Incomplete.framework', 'type': 'directory',
+          'contents': [
+            { 'name': 'Headers', 'type': 'directory',
+              'contents': [
+                { 'name': 'Incomplete.h', 'type': 'file',
+                  'external-contents': 'INPUT_DIR/Incomplete.h'
+                },
+                { 'name': 'IncompleteVFS.h', 'type': 'file',
+                  'external-contents': 'INPUT_DIR/IncompleteVFS.h'
+                }
+              ]
+            },
+            { 'name': 'Modules/module.modulemap', 'type': 'file',
+              'external-contents': 'INPUT_DIR/incomplete-umbrella.modulemap'
+            }
+          ]
         }
       ]
     }
diff --git a/test/VFS/incomplete-umbrella.m b/test/VFS/incomplete-umbrella.m
new file mode 100644
index 0000000..4e138cc
--- /dev/null
+++ b/test/VFS/incomplete-umbrella.m
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/Incomplete.framework/Headers
+// RUN: echo '// IncompleteReal.h' > %t/Incomplete.framework/Headers/IncompleteReal.h
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: not %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t \
+// RUN:     -ivfsoverlay %t.yaml -F %t -fsyntax-only %s 2>&1 | FileCheck %s
+// REQUIRES: shell
+
+@import Incomplete;
+// CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteVFS.h
+// CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteReal.h
+// CHECK: could not build module 'Incomplete'
diff --git a/test/lit.cfg b/test/lit.cfg
index 5c2b187..11e8e0b 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -471,18 +471,4 @@
 if use_gmalloc:
      config.environment.update({'DYLD_INSERT_LIBRARIES' : gmalloc_path_str})
 
-# On Darwin, support relocatable SDKs by providing Clang with a
-# default system root path.
-if 'darwin' in config.target_triple:
-    try:
-        cmd = subprocess.Popen(['xcrun', '--show-sdk-path'],
-                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        out, err = cmd.communicate()
-        out = out.strip()
-        res = cmd.wait()
-    except OSError:
-        res = -1
-    if res == 0 and out:
-        sdk_path = out
-        lit_config.note('using SDKROOT: %r' % sdk_path)
-        config.environment['SDKROOT'] = sdk_path
+lit.util.usePlatformSdkOnDarwin(config, lit_config)
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index 28331c2..a59a869 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -16,7 +16,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Signals.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 
 using namespace clang;
 using namespace arcmt;
@@ -81,10 +81,10 @@
 
 public:
   PrintTransforms(raw_ostream &OS)
-    : Ctx(0), OS(OS) { }
+    : Ctx(nullptr), OS(OS) {}
 
   void start(ASTContext &ctx) override { Ctx = &ctx; }
-  void finish() override { Ctx = 0; }
+  void finish() override { Ctx = nullptr; }
 
   void insert(SourceLocation loc, StringRef text) override {
     assert(Ctx);
@@ -112,7 +112,7 @@
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
       new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
   // Chain in -verify checker, if requested.
-  VerifyDiagnosticConsumer *verifyDiag = 0;
+  VerifyDiagnosticConsumer *verifyDiag = nullptr;
   if (VerifyDiags) {
     verifyDiag = new VerifyDiagnosticConsumer(*Diags);
     Diags->setClient(verifyDiag);
@@ -139,10 +139,8 @@
   PreprocessorOptions PPOpts;
   remapper.applyMappings(PPOpts);
   // The changed files will be in memory buffers, print them.
-  for (unsigned i = 0, e = PPOpts.RemappedFileBuffers.size(); i != e; ++i) {
-    const llvm::MemoryBuffer *mem = PPOpts.RemappedFileBuffers[i].second;
-    OS << mem->getBuffer();
-  }
+  for (const auto &RB : PPOpts.RemappedFileBuffers)
+    OS << RB.second->getBuffer();
 }
 
 static bool performTransformations(StringRef resourcesPath,
@@ -207,17 +205,15 @@
 static bool filesCompareEqual(StringRef fname1, StringRef fname2) {
   using namespace llvm;
 
-  std::unique_ptr<MemoryBuffer> file1;
-  MemoryBuffer::getFile(fname1, file1);
+  ErrorOr<std::unique_ptr<MemoryBuffer>> file1 = MemoryBuffer::getFile(fname1);
   if (!file1)
     return false;
 
-  std::unique_ptr<MemoryBuffer> file2;
-  MemoryBuffer::getFile(fname2, file2);
+  ErrorOr<std::unique_ptr<MemoryBuffer>> file2 = MemoryBuffer::getFile(fname2);
   if (!file2)
     return false;
 
-  return file1->getBuffer() == file2->getBuffer();
+  return file1.get()->getBuffer() == file2.get()->getBuffer();
 }
 
 static bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) {
@@ -238,18 +234,19 @@
     resultMap[sys::path::stem(fname)] = fname;
   }
 
-  std::unique_ptr<MemoryBuffer> inputBuf;
+  ErrorOr<std::unique_ptr<MemoryBuffer>> inputBuf = std::error_code();
   if (RemappingsFile.empty())
-    MemoryBuffer::getSTDIN(inputBuf);
+    inputBuf = MemoryBuffer::getSTDIN();
   else
-    MemoryBuffer::getFile(RemappingsFile, inputBuf);
+    inputBuf = MemoryBuffer::getFile(RemappingsFile);
   if (!inputBuf) {
     errs() << "error: could not read remappings input\n";
     return true;
   }
 
   SmallVector<StringRef, 8> strs;
-  inputBuf->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+  inputBuf.get()->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
+                                    /*KeepEmpty=*/false);
 
   if (strs.empty()) {
     errs() << "error: no files to verify from stdin\n";
diff --git a/tools/c-arcmt-test/c-arcmt-test.c b/tools/c-arcmt-test/c-arcmt-test.c
index 56a4132..3bbb2d5 100644
--- a/tools/c-arcmt-test/c-arcmt-test.c
+++ b/tools/c-arcmt-test/c-arcmt-test.c
@@ -97,14 +97,20 @@
 void thread_runner(void *client_data_v) {
   thread_info *client_data = client_data_v;
   client_data->result = carcmttest_main(client_data->argc, client_data->argv);
-#ifdef __CYGWIN__
-  fflush(stdout);  /* stdout is not flushed on Cygwin. */
-#endif
+}
+
+static void flush_atexit(void) {
+  /* stdout, and surprisingly even stderr, are not always flushed on process
+   * and thread exit, particularly when the system is under heavy load. */
+  fflush(stdout);
+  fflush(stderr);
 }
 
 int main(int argc, const char **argv) {
   thread_info client_data;
 
+  atexit(flush_atexit);
+
 #if defined(_WIN32)
   if (getenv("LIBCLANG_LOGGING") == NULL)
     putenv("LIBCLANG_LOGGING=1");
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index dcae670..07be22a 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1,10 +1,10 @@
 /* c-index-test.c */
 
+#include "clang/Config/config.h"
 #include "clang-c/Index.h"
 #include "clang-c/CXCompilationDatabase.h"
 #include "clang-c/BuildSystem.h"
 #include "clang-c/Documentation.h"
-#include "llvm/Config/config.h"
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -4116,14 +4116,20 @@
 void thread_runner(void *client_data_v) {
   thread_info *client_data = client_data_v;
   client_data->result = cindextest_main(client_data->argc, client_data->argv);
-#ifdef __CYGWIN__
-  fflush(stdout);  /* stdout is not flushed on Cygwin. */
-#endif
+}
+
+static void flush_atexit(void) {
+  /* stdout, and surprisingly even stderr, are not always flushed on process
+   * and thread exit, particularly when the system is under heavy load. */
+  fflush(stdout);
+  fflush(stderr);
 }
 
 int main(int argc, const char **argv) {
   thread_info client_data;
 
+  atexit(flush_atexit);
+
 #ifdef CLANG_HAVE_LIBXML
   LIBXML_TEST_VERSION
 #endif
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index 189a611..cebb275 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -103,7 +103,7 @@
 namespace clang {
 namespace format {
 
-static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,
+static FileID createInMemoryFile(StringRef FileName, MemoryBuffer *Source,
                                  SourceManager &Sources, FileManager &Files) {
   const FileEntry *Entry = Files.getVirtualFile(FileName == "-" ? "<stdin>" :
                                                     FileName,
@@ -209,11 +209,13 @@
       IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
       new DiagnosticOptions);
   SourceManager Sources(Diagnostics, Files);
-  std::unique_ptr<MemoryBuffer> Code;
-  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
-    llvm::errs() << ec.message() << "\n";
+  ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
+      MemoryBuffer::getFileOrSTDIN(FileName);
+  if (std::error_code EC = CodeOrErr.getError()) {
+    llvm::errs() << EC.message() << "\n";
     return true;
   }
+  std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
   if (Code->getBufferSize() == 0)
     return false; // Empty files are formatted correctly.
   FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
diff --git a/tools/diagtool/DiagTool.cpp b/tools/diagtool/DiagTool.cpp
index c3428c9..44bc83e 100644
--- a/tools/diagtool/DiagTool.cpp
+++ b/tools/diagtool/DiagTool.cpp
@@ -32,7 +32,7 @@
 
 DiagTool *DiagTools::getTool(llvm::StringRef toolCmd) {
   ToolMap::iterator it = getTools(tools)->find(toolCmd);
-  return (it == getTools(tools)->end()) ? 0 : it->getValue();
+  return (it == getTools(tools)->end()) ? nullptr : it->getValue();
 }
 
 void DiagTools::registerTool(DiagTool *tool) {
diff --git a/tools/diagtool/DiagnosticNames.cpp b/tools/diagtool/DiagnosticNames.cpp
index f5df059..a08da89 100644
--- a/tools/diagtool/DiagnosticNames.cpp
+++ b/tools/diagtool/DiagnosticNames.cpp
@@ -50,7 +50,7 @@
 }
 
 const DiagnosticRecord &diagtool::getDiagnosticForID(short DiagID) {
-  DiagnosticRecord Key = {0, DiagID, 0};
+  DiagnosticRecord Key = {nullptr, DiagID, 0};
 
   const DiagnosticRecord *Result =
     std::lower_bound(std::begin(BuiltinDiagnosticsByID),
@@ -81,7 +81,7 @@
 }
 
 GroupRecord::subgroup_iterator GroupRecord::subgroup_end() const {
-  return 0;
+  return nullptr;
 }
 
 GroupRecord::diagnostics_iterator GroupRecord::diagnostics_begin() const {
@@ -89,7 +89,7 @@
 }
 
 GroupRecord::diagnostics_iterator GroupRecord::diagnostics_end() const {
-  return 0;
+  return nullptr;
 }
 
 llvm::ArrayRef<GroupRecord> diagtool::getDiagnosticGroups() {
diff --git a/tools/diagtool/DiagnosticNames.h b/tools/diagtool/DiagnosticNames.h
index a3321fa..2571b19 100644
--- a/tools/diagtool/DiagnosticNames.h
+++ b/tools/diagtool/DiagnosticNames.h
@@ -48,7 +48,7 @@
       friend struct GroupRecord;
       group_iterator(const short *Start) : CurrentID(Start) {
         if (CurrentID && *CurrentID == -1)
-          CurrentID = 0;
+          CurrentID = nullptr;
       }
 
     public:
@@ -70,7 +70,7 @@
       group_iterator &operator++() {
         ++CurrentID;
         if (*CurrentID == -1)
-          CurrentID = 0;
+          CurrentID = nullptr;
         return *this;
       }
 
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index ad56b03..903d1f1 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -68,14 +68,14 @@
       createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc),
                                       InterimDiags));
   if (!Invocation)
-    return NULL;
+    return nullptr;
 
   // Build the diagnostics parser
   IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags =
     CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts());
   if (!FinalDiags)
-    return NULL;
-  
+    return nullptr;
+
   // Flush any errors created when initializing everything. This could happen
   // for invalid command lines, which will probably give non-sensical results.
   DiagsBuffer->FlushDiagnostics(*FinalDiags);
diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp
index fd548ef..3647e39 100644
--- a/tools/diagtool/TreeView.cpp
+++ b/tools/diagtool/TreeView.cpp
@@ -6,10 +6,6 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-// This diagnostic tool 
-//
-//===----------------------------------------------------------------------===//
 
 #include "DiagTool.h"
 #include "DiagnosticNames.h"
@@ -22,118 +18,129 @@
 #include "llvm/Support/Format.h"
 #include "llvm/Support/Process.h"
 
-DEF_DIAGTOOL("tree",
-             "Show warning flags in a tree view",
-             TreeView)
-  
+DEF_DIAGTOOL("tree", "Show warning flags in a tree view", TreeView)
+
 using namespace clang;
 using namespace diagtool;
 
-static void printUsage() {
-  llvm::errs() << "Usage: diagtool tree [--flags-only] [<diagnostic-group>]\n";
-}
-
-static bool showColors(llvm::raw_ostream &out) {
+static bool hasColors(const llvm::raw_ostream &out) {
   if (&out != &llvm::errs() && &out != &llvm::outs())
     return false;
   return llvm::errs().is_displayed() && llvm::outs().is_displayed();
 }
 
-static void setColor(bool ShowColors, llvm::raw_ostream &out,
-                     llvm::raw_ostream::Colors Color) {
-  if (ShowColors)
-    out << llvm::sys::Process::OutputColor(Color, false, false);
-}
+class TreePrinter {
+public:
+  llvm::raw_ostream &out;
+  const bool ShowColors;
+  bool FlagsOnly;
 
-static void resetColor(bool ShowColors, llvm::raw_ostream &out) {
-  if (ShowColors)
-    out << llvm::sys::Process::ResetColor();
-}
+  TreePrinter(llvm::raw_ostream &out)
+      : out(out), ShowColors(hasColors(out)), FlagsOnly(false) {}
 
-static clang::DiagnosticsEngine::Level getLevel(unsigned DiagID) {
-  // FIXME: This feels like a hack.
-  static clang::DiagnosticsEngine Diags(new DiagnosticIDs,
-                                        new DiagnosticOptions);
-  return Diags.getDiagnosticLevel(DiagID, SourceLocation());
-}
-
-static void printGroup(llvm::raw_ostream &out, const GroupRecord &Group,
-                       bool FlagsOnly, unsigned Indent = 0) {
-  out.indent(Indent * 2);
-  
-  bool ShowColors = showColors(out);
-  setColor(ShowColors, out, llvm::raw_ostream::YELLOW);
-  out << "-W" << Group.getName() << "\n";
-  resetColor(ShowColors, out);
-  
-  ++Indent;
-  for (GroupRecord::subgroup_iterator I = Group.subgroup_begin(),
-                                      E = Group.subgroup_end();
-       I != E; ++I) {
-    printGroup(out, *I, FlagsOnly, Indent);
+  void setColor(llvm::raw_ostream::Colors Color) {
+    if (ShowColors)
+      out << llvm::sys::Process::OutputColor(Color, false, false);
   }
 
-  if (!FlagsOnly) {
-    for (GroupRecord::diagnostics_iterator I = Group.diagnostics_begin(),
-                                           E = Group.diagnostics_end();
+  void resetColor() {
+    if (ShowColors)
+      out << llvm::sys::Process::ResetColor();
+  }
+
+  static bool isIgnored(unsigned DiagID) {
+    // FIXME: This feels like a hack.
+    static clang::DiagnosticsEngine Diags(new DiagnosticIDs,
+                                          new DiagnosticOptions);
+    return Diags.isIgnored(DiagID, SourceLocation());
+  }
+
+  void printGroup(const GroupRecord &Group, unsigned Indent = 0) {
+    out.indent(Indent * 2);
+
+    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) {
-      if (ShowColors) {
-        if (getLevel(I->DiagID) != DiagnosticsEngine::Ignored) {
-          setColor(ShowColors, out, llvm::raw_ostream::GREEN);
-        }
+      printGroup(*I, Indent);
+    }
+
+    if (!FlagsOnly) {
+      for (GroupRecord::diagnostics_iterator I = Group.diagnostics_begin(),
+                                             E = Group.diagnostics_end();
+           I != E; ++I) {
+        if (ShowColors && !isIgnored(I->DiagID))
+          setColor(llvm::raw_ostream::GREEN);
+        out.indent(Indent * 2);
+        out << I->getName();
+        resetColor();
+        out << "\n";
       }
-      out.indent(Indent * 2);
-      out << I->getName();
-      resetColor(ShowColors, out);
-      out << "\n";
-    }
-  }
-}
-
-static int showGroup(llvm::raw_ostream &out, StringRef RootGroup,
-                     bool FlagsOnly) {
-  ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
-
-  if (RootGroup.size() > UINT16_MAX) {
-    llvm::errs() << "No such diagnostic group exists\n";
-    return 1;
-  }
-
-  const GroupRecord *Found =
-    std::lower_bound(AllGroups.begin(), AllGroups.end(), RootGroup);
-  
-  if (Found == AllGroups.end() || Found->getName() != RootGroup) {
-    llvm::errs() << "No such diagnostic group exists\n";
-    return 1;
-  }
-  
-  printGroup(out, *Found, FlagsOnly);
-  
-  return 0;
-}
-
-static int showAll(llvm::raw_ostream &out, bool FlagsOnly) {
-  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) {
-      NonRootGroupIDs.insert((unsigned)SI.getID());
     }
   }
 
-  assert(NonRootGroupIDs.size() < AllGroups.size());
+  int showGroup(StringRef RootGroup) {
+    ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
 
-  for (unsigned i = 0, e = AllGroups.size(); i != e; ++i) {
-    if (!NonRootGroupIDs.count(i))
-      printGroup(out, AllGroups[i], FlagsOnly);
+    if (RootGroup.size() > UINT16_MAX) {
+      llvm::errs() << "No such diagnostic group exists\n";
+      return 1;
+    }
+
+    const GroupRecord *Found =
+        std::lower_bound(AllGroups.begin(), AllGroups.end(), RootGroup);
+
+    if (Found == AllGroups.end() || Found->getName() != RootGroup) {
+      llvm::errs() << "No such diagnostic group exists\n";
+      return 1;
+    }
+
+    printGroup(*Found);
+
+    return 0;
   }
 
-  return 0;
+  int showAll() {
+    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) {
+        NonRootGroupIDs.insert((unsigned)SI.getID());
+      }
+    }
+
+    assert(NonRootGroupIDs.size() < AllGroups.size());
+
+    for (unsigned i = 0, e = AllGroups.size(); i != e; ++i) {
+      if (!NonRootGroupIDs.count(i))
+        printGroup(AllGroups[i]);
+    }
+
+    return 0;
+  }
+
+  void showKey() {
+    if (ShowColors) {
+      out << '\n';
+      setColor(llvm::raw_ostream::GREEN);
+      out << "GREEN";
+      resetColor();
+      out << " = enabled by default\n\n";
+    }
+  }
+};
+
+static void printUsage() {
+  llvm::errs() << "Usage: diagtool tree [--flags-only] [<diagnostic-group>]\n";
 }
 
 int TreeView::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
@@ -147,7 +154,7 @@
       ++argv;
     }
   }
-  
+
   bool ShowAll = false;
   StringRef RootGroup;
 
@@ -168,17 +175,8 @@
     return -1;
   }
 
-  if (showColors(out)) {
-    out << '\n';
-    setColor(true, out, llvm::raw_ostream::GREEN);
-    out << "GREEN";
-    resetColor(true, out);
-    out << " = enabled by default\n\n";
-  }
-  
-  if (ShowAll)
-    return showAll(out, FlagsOnly);
-
-  return showGroup(out, RootGroup, FlagsOnly);
+  TreePrinter TP(out);
+  TP.FlagsOnly = FlagsOnly;
+  TP.showKey();
+  return ShowAll ? TP.showAll() : TP.showGroup(RootGroup);
 }
-
diff --git a/tools/driver/Android.mk b/tools/driver/Android.mk
index 9941ea8..4caba8f 100644
--- a/tools/driver/Android.mk
+++ b/tools/driver/Android.mk
@@ -113,6 +113,8 @@
     $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(CLANG_CXX)
 # the additional dependency is needed when you run mm/mmm.
 $(LOCAL_MODULE) : $(CLANG_CXX)
+CLANG_ARM_NEON_H := $(TARGET_OUT_HEADERS)/clang/arm_neon.h
+$(LOCAL_MODULE) : $(CLANG_ARM_NEON_H)
 
 # Symlink for clang++
 $(CLANG_CXX) : $(LOCAL_INSTALLED_MODULE)
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 67d2115..910732e 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -1,6 +1,7 @@
 set( LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
   Analysis
+  CodeGen
   Core
   IPA
   IPO
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index c4456e2..e41bc9f 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -14,7 +14,6 @@
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Driver/CC1AsOptions.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
@@ -53,10 +52,11 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include <memory>
+#include <system_error>
 using namespace clang;
 using namespace clang::driver;
+using namespace clang::driver::options;
 using namespace llvm;
 using namespace llvm::opt;
 
@@ -151,26 +151,29 @@
                                          const char **ArgBegin,
                                          const char **ArgEnd,
                                          DiagnosticsEngine &Diags) {
-  using namespace clang::driver::cc1asoptions;
   bool Success = true;
 
   // Parse the arguments.
-  std::unique_ptr<OptTable> OptTbl(createCC1AsOptTable());
+  std::unique_ptr<OptTable> OptTbl(createDriverOptTable());
+
+  const unsigned IncludedFlagsBitmask = options::CC1AsOption;
   unsigned MissingArgIndex, MissingArgCount;
   std::unique_ptr<InputArgList> Args(
-      OptTbl->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
+      OptTbl->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount,
+                        IncludedFlagsBitmask));
 
   // Check for missing argument error.
   if (MissingArgCount) {
     Diags.Report(diag::err_drv_missing_argument)
-      << Args->getArgString(MissingArgIndex) << MissingArgCount;
+        << Args->getArgString(MissingArgIndex) << MissingArgCount;
     Success = false;
   }
 
   // Issue errors on unknown arguments.
-  for (arg_iterator it = Args->filtered_begin(cc1asoptions::OPT_UNKNOWN),
-         ie = Args->filtered_end(); it != ie; ++it) {
-    Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args);
+  for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
+                    ie = Args->filtered_end();
+       it != ie; ++it) {
+    Diags.Report(diag::err_drv_unknown_argument) << (*it)->getAsString(*Args);
     Success = false;
   }
 
@@ -189,7 +192,7 @@
   Opts.IncludePaths = Args->getAllArgValues(OPT_I);
   Opts.NoInitialTextSection = Args->hasArg(OPT_n);
   Opts.SaveTemporaryLabels = Args->hasArg(OPT_msave_temp_labels);
-  Opts.GenDwarfForAssembly = Args->hasArg(OPT_g);
+  Opts.GenDwarfForAssembly = Args->hasArg(OPT_g_Flag);
   Opts.CompressDebugSections = Args->hasArg(OPT_compress_debug_sections);
   if (Args->hasArg(OPT_gdwarf_2))
     Opts.DwarfVersion = 2;
@@ -266,7 +269,8 @@
   if (!Error.empty()) {
     Diags.Report(diag::err_fe_unable_to_open_output)
       << Opts.OutputPath << Error;
-    return 0;
+    delete Out;
+    return nullptr;
   }
 
   return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM);
@@ -276,24 +280,22 @@
                              DiagnosticsEngine &Diags) {
   // Get the target specific parser.
   std::string Error;
-  const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error));
-  if (!TheTarget) {
-    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
-    return false;
-  }
+  const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
+  if (!TheTarget)
+    return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
 
-  std::unique_ptr<MemoryBuffer> BufferPtr;
-  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) {
-    Error = ec.message();
-    Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
-    return false;
+  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
+      MemoryBuffer::getFileOrSTDIN(Opts.InputFile);
+
+  if (std::error_code EC = Buffer.getError()) {
+    Error = EC.message();
+    return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
   }
-  MemoryBuffer *Buffer = BufferPtr.release();
 
   SourceMgr SrcMgr;
 
   // Tell SrcMgr about this buffer, which is what the parser will pick up.
-  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
+  SrcMgr.AddNewSourceBuffer(Buffer->release(), SMLoc());
 
   // Record the location of the include directories so that the lexer can find
   // it later.
@@ -311,9 +313,10 @@
     MAI->setCompressDebugSections(true);
 
   bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
-  formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
+  std::unique_ptr<formatted_raw_ostream> Out(
+      GetOutputStream(Opts, Diags, IsBinary));
   if (!Out)
-    return false;
+    return true;
 
   // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
   // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
@@ -356,8 +359,8 @@
     MCInstPrinter *IP =
       TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
                                      *STI);
-    MCCodeEmitter *CE = 0;
-    MCAsmBackend *MAB = 0;
+    MCCodeEmitter *CE = nullptr;
+    MCAsmBackend *MAB = nullptr;
     if (Opts.ShowEncoding) {
       CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
       MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
@@ -380,6 +383,8 @@
     Str.get()->InitSections();
   }
 
+  bool Failed = false;
+
   std::unique_ptr<MCAsmParser> Parser(
       createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
 
@@ -387,23 +392,22 @@
   MCTargetOptions Options;
   std::unique_ptr<MCTargetAsmParser> TAP(
       TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
-  if (!TAP) {
-    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
-    return false;
+  if (!TAP)
+    Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
+
+  if (!Failed) {
+    Parser->setTargetParser(*TAP.get());
+    Failed = Parser->Run(Opts.NoInitialTextSection);
   }
 
-  Parser->setTargetParser(*TAP.get());
+  // Close the output stream early.
+  Out.reset();
 
-  bool Success = !Parser->Run(Opts.NoInitialTextSection);
-
-  // Close the output.
-  delete Out;
-
-  // Delete output on errors.
-  if (!Success && Opts.OutputPath != "-")
+  // Delete output file if there were errors.
+  if (Failed && Opts.OutputPath != "-")
     sys::fs::remove(Opts.OutputPath);
 
-  return Success;
+  return Failed;
 }
 
 static void LLVMErrorHandler(void *UserData, const std::string &Message,
@@ -446,10 +450,10 @@
   if (!AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags))
     return 1;
 
-  // Honor -help.
   if (Asm.ShowHelp) {
-    std::unique_ptr<OptTable> Opts(driver::createCC1AsOptTable());
-    Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler");
+    std::unique_ptr<OptTable> Opts(driver::createDriverOptTable());
+    Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler",
+                    /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0);
     return 0;
   }
 
@@ -470,18 +474,17 @@
     Args[0] = "clang (LLVM option parsing)";
     for (unsigned i = 0; i != NumArgs; ++i)
       Args[i + 1] = Asm.LLVMArgs[i].c_str();
-    Args[NumArgs + 1] = 0;
+    Args[NumArgs + 1] = nullptr;
     llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
   }
 
   // Execute the invocation, unless there were parsing errors.
-  bool Success = false;
-  if (!Diags.hasErrorOccurred())
-    Success = ExecuteAssembler(Asm, Diags);
+  bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags);
 
   // If any timers were active but haven't been destroyed yet, print their
   // results now.
   TimerGroup::printAll(errs());
 
-  return !Success;
+  return !!Failed;
 }
+
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index fd13555..9f93837 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -25,7 +25,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/OptTable.h"
 #include "llvm/Option/Option.h"
@@ -45,8 +45,8 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include <memory>
+#include <system_error>
 using namespace clang;
 using namespace clang::driver;
 using namespace llvm::opt;
@@ -214,15 +214,15 @@
     const char *Suffix;
     const char *ModeFlag;
   } suffixes [] = {
-    { "clang",     0 },
+    { "clang",     nullptr },
     { "clang++",   "--driver-mode=g++" },
     { "clang-c++", "--driver-mode=g++" },
-    { "clang-cc",  0 },
+    { "clang-cc",  nullptr },
     { "clang-cpp", "--driver-mode=cpp" },
     { "clang-g++", "--driver-mode=g++" },
-    { "clang-gcc", 0 },
+    { "clang-gcc", nullptr },
     { "clang-cl",  "--driver-mode=cl"  },
-    { "cc",        0 },
+    { "cc",        nullptr },
     { "cpp",       "--driver-mode=cpp" },
     { "cl" ,       "--driver-mode=cl"  },
     { "++",        "--driver-mode=g++" },
@@ -299,8 +299,8 @@
 
   SmallVector<const char *, 256> argv;
   llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
-  llvm::error_code EC = llvm::sys::Process::GetArgumentVector(
-      argv, llvm::ArrayRef<const char *>(argv_, argc_), ArgAllocator);
+  std::error_code EC = llvm::sys::Process::GetArgumentVector(
+      argv, ArrayRef<const char *>(argv_, argc_), ArgAllocator);
   if (EC) {
     llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
     return 1;
@@ -420,7 +420,7 @@
   // Force a crash to test the diagnostics.
   if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
     Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
-    const Command *FailingCommand = 0;
+    const Command *FailingCommand = nullptr;
     FailingCommands.push_back(std::make_pair(-1, FailingCommand));
   }
 
@@ -433,8 +433,13 @@
 
     // If result status is < 0, then the driver command signalled an error.
     // If result status is 70, then the driver command reported a fatal error.
-    // In these cases, generate additional diagnostic information if possible.
-    if (CommandRes < 0 || CommandRes == 70) {
+    // On Windows, abort will return an exit code of 3.  In these cases,
+    // generate additional diagnostic information if possible.
+    bool DiagnoseCrash = CommandRes < 0 || CommandRes == 70;
+#ifdef LLVM_ON_WIN32
+    DiagnoseCrash |= CommandRes == 3;
+#endif
+    if (DiagnoseCrash) {
       TheDriver.generateCompilationDiagnostics(*C, FailingCommand);
       break;
     }
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index dbb604d..6ddc22f 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -40,7 +40,7 @@
   if (!migrate_dir_path) {
     if (Logging)
       llvm::errs() << "clang_getRemappings was called with NULL parameter\n";
-    return 0;
+    return nullptr;
   }
 
   bool exists = false;
@@ -51,7 +51,7 @@
                    << "\")\n";
       llvm::errs() << "\"" << migrate_dir_path << "\" does not exist\n";
     }
-    return 0;
+    return nullptr;
   }
 
   TextDiagnosticBuffer diagBuffer;
@@ -67,7 +67,7 @@
              I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I)
         llvm::errs() << I->second << '\n';
     }
-    return 0;
+    return nullptr;
   }
 
   return remap.release();
@@ -90,7 +90,7 @@
     if (Logging)
       llvm::errs() << "clang_getRemappingsFromFileList was called with "
                       "NULL filePaths\n";
-    return 0;
+    return nullptr;
   }
 
   TextDiagnosticBuffer diagBuffer;
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index bc1174a..5bfac51 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -39,10 +39,11 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Mutex.h"
 #include "llvm/Support/Program.h"
@@ -52,7 +53,11 @@
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
 
-#if HAVE_PTHREAD_H
+#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
+#define USE_DARWIN_THREADS
+#endif
+
+#ifdef USE_DARWIN_THREADS
 #include <pthread.h>
 #endif
 
@@ -63,15 +68,15 @@
 
 CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
   if (!AU)
-    return 0;
+    return nullptr;
   assert(CIdx);
   CXTranslationUnit D = new CXTranslationUnitImpl();
   D->CIdx = CIdx;
   D->TheASTUnit = AU;
   D->StringPool = new cxstring::CXStringPool();
-  D->Diagnostics = 0;
+  D->Diagnostics = nullptr;
   D->OverridenCursorsPool = createOverridenCXCursorsPool();
-  D->CommentToXML = 0;
+  D->CommentToXML = nullptr;
   return D;
 }
 
@@ -321,7 +326,7 @@
   assert(!Decls.empty());
 
   bool VisitedAtLeastOnce = false;
-  DeclContext *CurDC = 0;
+  DeclContext *CurDC = nullptr;
   SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
   for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
     Decl *D = *DIt;
@@ -350,7 +355,7 @@
       FileDI_current = &DIt;
       FileDE_current = DE;
     } else {
-      FileDI_current = 0;
+      FileDI_current = nullptr;
     }
 
     if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
@@ -1703,7 +1708,7 @@
 public:
   DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
     VisitorJob(parent, VisitorJob::DeclVisitKind,
-               D, isFirst ? (void*) 1 : (void*) 0) {}
+               D, isFirst ? (void*) 1 : (void*) nullptr) {}
   static bool classof(const VisitorJob *VJ) {
     return VJ->getKind() == DeclVisitKind;
   }
@@ -1851,6 +1856,12 @@
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPParallelDirective(const OMPParallelDirective *D);
   void VisitOMPSimdDirective(const OMPSimdDirective *D);
+  void VisitOMPForDirective(const OMPForDirective *D);
+  void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
+  void VisitOMPSectionDirective(const OMPSectionDirective *D);
+  void VisitOMPSingleDirective(const OMPSingleDirective *D);
+  void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
+  void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
 
 private:
   void AddDeclarationNameInfo(const Stmt *S);
@@ -1943,6 +1954,14 @@
 
 void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
 
+void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
+  Visitor->AddStmt(C->getChunkSize());
+}
+
+void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
+
+void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
+
 template<typename T>
 void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
   for (const auto *I : Node->varlists())
@@ -1956,16 +1975,31 @@
                                         const OMPFirstprivateClause *C) {
   VisitOMPClauseList(C);
 }
+void OMPClauseEnqueue::VisitOMPLastprivateClause(
+                                        const OMPLastprivateClause *C) {
+  VisitOMPClauseList(C);
+}
 void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
   VisitOMPClauseList(C);
 }
+void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
+  VisitOMPClauseList(C);
+}
 void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
   VisitOMPClauseList(C);
   Visitor->AddStmt(C->getStep());
 }
+void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+  VisitOMPClauseList(C);
+  Visitor->AddStmt(C->getAlignment());
+}
 void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
   VisitOMPClauseList(C);
 }
+void
+OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
+  VisitOMPClauseList(C);
+}
 }
 
 void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
@@ -2263,6 +2297,32 @@
   VisitOMPExecutableDirective(D);
 }
 
+void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void
+EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPParallelSectionsDirective(
+    const OMPParallelSectionsDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
 }
@@ -2358,7 +2418,7 @@
           case CXChildVisit_Continue: break;
           case CXChildVisit_Recurse:
             if (PostChildrenVisitor)
-              WL.push_back(PostChildrenVisit(0, Cursor));
+              WL.push_back(PostChildrenVisit(nullptr, Cursor));
             EnqueueWorkList(WL, S);
             break;
         }
@@ -2487,7 +2547,7 @@
 }
 
 bool CursorVisitor::Visit(const Stmt *S) {
-  VisitorWorkList *WL = 0;
+  VisitorWorkList *WL = nullptr;
   if (!WorkListFreeList.empty()) {
     WL = WorkListFreeList.back();
     WL->clear();
@@ -2505,10 +2565,10 @@
 
 namespace {
 typedef SmallVector<SourceRange, 4> RefNamePieces;
-RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr, 
-                          const DeclarationNameInfo &NI, 
-                          const SourceRange &QLoc, 
-                          const ASTTemplateArgumentListInfo *TemplateArgs = 0){
+RefNamePieces
+buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
+            const DeclarationNameInfo &NI, const SourceRange &QLoc,
+            const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
   const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
   const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
   const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
@@ -2548,9 +2608,6 @@
 // Misc. API hooks.
 //===----------------------------------------------------------------------===//               
 
-static llvm::sys::Mutex EnableMultithreadingMutex;
-static bool EnabledMultithreading;
-
 static void fatal_error_handler(void *user_data, const std::string& reason,
                                 bool gen_crash_diag) {
   // Write the result out to stderr avoiding errs() because raw_ostreams can
@@ -2559,6 +2616,16 @@
   ::abort();
 }
 
+namespace {
+struct RegisterFatalErrorHandler {
+  RegisterFatalErrorHandler() {
+    llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
+  }
+};
+}
+
+static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
+
 extern "C" {
 CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
                           int displayDiagnostics) {
@@ -2567,15 +2634,10 @@
   if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
     llvm::CrashRecoveryContext::Enable();
 
-  // Enable support for multithreading in LLVM.
-  {
-    llvm::sys::ScopedLock L(EnableMultithreadingMutex);
-    if (!EnabledMultithreading) {
-      llvm::install_fatal_error_handler(fatal_error_handler, 0);
-      llvm::llvm_start_multithreaded();
-      EnabledMultithreading = true;
-    }
-  }
+  // Look through the managed static to trigger construction of the managed
+  // static which registers our fatal error handler. This ensures it is only
+  // registered once.
+  (void)*RegisterFatalErrorHandlerOnce;
 
   CIndexer *CIdxr = new CIndexer();
   if (excludeDeclarationsFromPCH)
@@ -2631,7 +2693,7 @@
                                               const char *ast_filename,
                                               CXTranslationUnit *out_TU) {
   if (out_TU)
-    *out_TU = NULL;
+    *out_TU = nullptr;
 
   if (!CIdx || !ast_filename || !out_TU)
     return CXError_InvalidArguments;
@@ -2677,32 +2739,27 @@
   const char *source_filename;
   const char *const *command_line_args;
   int num_command_line_args;
-  struct CXUnsavedFile *unsaved_files;
-  unsigned num_unsaved_files;
+  ArrayRef<CXUnsavedFile> unsaved_files;
   unsigned options;
   CXTranslationUnit *out_TU;
-  CXErrorCode result;
+  CXErrorCode &result;
 };
 static void clang_parseTranslationUnit_Impl(void *UserData) {
-  ParseTranslationUnitInfo *PTUI =
-    static_cast<ParseTranslationUnitInfo*>(UserData);
+  const ParseTranslationUnitInfo *PTUI =
+      static_cast<ParseTranslationUnitInfo *>(UserData);
   CXIndex CIdx = PTUI->CIdx;
   const char *source_filename = PTUI->source_filename;
   const char * const *command_line_args = PTUI->command_line_args;
   int num_command_line_args = PTUI->num_command_line_args;
-  struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
-  unsigned num_unsaved_files = PTUI->num_unsaved_files;
   unsigned options = PTUI->options;
   CXTranslationUnit *out_TU = PTUI->out_TU;
 
   // Set up the initial return values.
   if (out_TU)
-    *out_TU = NULL;
-  PTUI->result = CXError_Failure;
+    *out_TU = nullptr;
 
   // Check arguments.
-  if (!CIdx || !out_TU ||
-      (unsaved_files == NULL && num_unsaved_files != 0)) {
+  if (!CIdx || !out_TU) {
     PTUI->result = CXError_InvalidArguments;
     return;
   }
@@ -2730,7 +2787,7 @@
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
   std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
       new std::vector<ASTUnit::RemappedFile>());
@@ -2739,12 +2796,10 @@
   llvm::CrashRecoveryContextCleanupRegistrar<
     std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
 
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
-                                            Buffer));
+  for (auto &UF : PTUI->unsaved_files) {
+    llvm::MemoryBuffer *MB =
+        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+    RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
   }
 
   std::unique_ptr<std::vector<const char *>> Args(
@@ -2845,10 +2900,19 @@
       *Log << command_line_args[i] << " ";
   }
 
-  ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
-                                    num_command_line_args, unsaved_files,
-                                    num_unsaved_files, options, out_TU,
-                                    CXError_Failure };
+  if (num_unsaved_files && !unsaved_files)
+    return CXError_InvalidArguments;
+
+  CXErrorCode result = CXError_Failure;
+  ParseTranslationUnitInfo PTUI = {
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      llvm::makeArrayRef(unsaved_files, num_unsaved_files),
+      options,
+      out_TU,
+      result};
   llvm::CrashRecoveryContext CRC;
 
   if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
@@ -2877,8 +2941,8 @@
     if (CXTranslationUnit *TU = PTUI.out_TU)
       PrintLibclangResourceUsage(*TU);
   }
-  
-  return PTUI.result;
+
+  return result;
 }
 
 unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
@@ -2979,20 +3043,15 @@
 
 struct ReparseTranslationUnitInfo {
   CXTranslationUnit TU;
-  unsigned num_unsaved_files;
-  struct CXUnsavedFile *unsaved_files;
+  ArrayRef<CXUnsavedFile> unsaved_files;
   unsigned options;
-  int result;
+  CXErrorCode &result;
 };
 
 static void clang_reparseTranslationUnit_Impl(void *UserData) {
-  ReparseTranslationUnitInfo *RTUI =
-    static_cast<ReparseTranslationUnitInfo*>(UserData);
-  RTUI->result = CXError_Failure;
-
+  const ReparseTranslationUnitInfo *RTUI =
+      static_cast<ReparseTranslationUnitInfo *>(UserData);
   CXTranslationUnit TU = RTUI->TU;
-  unsigned num_unsaved_files = RTUI->num_unsaved_files;
-  struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
   unsigned options = RTUI->options;
   (void) options;
 
@@ -3002,14 +3061,10 @@
     RTUI->result = CXError_InvalidArguments;
     return;
   }
-  if (unsaved_files == NULL && num_unsaved_files != 0) {
-    RTUI->result = CXError_InvalidArguments;
-    return;
-  }
 
   // Reset the associated diagnostics.
   delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
-  TU->Diagnostics = 0;
+  TU->Diagnostics = nullptr;
 
   CIndexer *CXXIdx = TU->CIdx;
   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
@@ -3024,13 +3079,11 @@
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<
     std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
-  
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
-                                            Buffer));
+
+  for (auto &UF : RTUI->unsaved_files) {
+    llvm::MemoryBuffer *MB =
+        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+    RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
   }
 
   if (!CXXUnit->Reparse(*RemappedFiles.get()))
@@ -3047,12 +3100,17 @@
     *Log << TU;
   }
 
-  ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
-                                      options, CXError_Failure };
+  if (num_unsaved_files && !unsaved_files)
+    return CXError_InvalidArguments;
+
+  CXErrorCode result = CXError_Failure;
+  ReparseTranslationUnitInfo RTUI = {
+      TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
+      result};
 
   if (getenv("LIBCLANG_NOTHREADS")) {
     clang_reparseTranslationUnit_Impl(&RTUI);
-    return RTUI.result;
+    return result;
   }
 
   llvm::CrashRecoveryContext CRC;
@@ -3064,7 +3122,7 @@
   } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
     PrintLibclangResourceUsage(TU);
 
-  return RTUI.result;
+  return result;
 }
 
 
@@ -3114,7 +3172,7 @@
 CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
   if (isNotUsableTU(TU)) {
     LOG_BAD_TU(TU);
-    return 0;
+    return nullptr;
   }
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -3201,8 +3259,8 @@
     if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) || 
         isa<ParmVarDecl>(SizeOfPack->getPack()))
       return SizeOfPack->getPack();
-  
-  return 0;
+
+  return nullptr;
 }
 
 static SourceLocation getLocationFromExpr(const Expr *E) {
@@ -3843,6 +3901,8 @@
       return cxstring::createRef("SEHExceptStmt");
   case CXCursor_SEHFinallyStmt:
       return cxstring::createRef("SEHFinallyStmt");
+  case CXCursor_SEHLeaveStmt:
+      return cxstring::createRef("SEHLeaveStmt");
   case CXCursor_NullStmt:
       return cxstring::createRef("NullStmt");
   case CXCursor_InvalidFile:
@@ -3879,6 +3939,14 @@
     return cxstring::createRef("attribute(const)");
   case CXCursor_NoDuplicateAttr:
     return cxstring::createRef("attribute(noduplicate)");
+  case CXCursor_CUDAConstantAttr:
+    return cxstring::createRef("attribute(constant)");
+  case CXCursor_CUDADeviceAttr:
+    return cxstring::createRef("attribute(device)");
+  case CXCursor_CUDAGlobalAttr:
+    return cxstring::createRef("attribute(global)");
+  case CXCursor_CUDAHostAttr:
+    return cxstring::createRef("attribute(host)");
   case CXCursor_PreprocessingDirective:
     return cxstring::createRef("preprocessing directive");
   case CXCursor_MacroDefinition:
@@ -3931,6 +3999,18 @@
     return cxstring::createRef("OMPParallelDirective");
   case CXCursor_OMPSimdDirective:
     return cxstring::createRef("OMPSimdDirective");
+  case CXCursor_OMPForDirective:
+    return cxstring::createRef("OMPForDirective");
+  case CXCursor_OMPSectionsDirective:
+    return cxstring::createRef("OMPSectionsDirective");
+  case CXCursor_OMPSectionDirective:
+    return cxstring::createRef("OMPSectionDirective");
+  case CXCursor_OMPSingleDirective:
+    return cxstring::createRef("OMPSingleDirective");
+  case CXCursor_OMPParallelForDirective:
+    return cxstring::createRef("OMPParallelForDirective");
+  case CXCursor_OMPParallelSectionsDirective:
+    return cxstring::createRef("OMPParallelSectionsDirective");
   }
 
   llvm_unreachable("Unhandled CXCursorKind");
@@ -4066,10 +4146,11 @@
     CXString SearchFileName, ResultFileName, KindSpelling, USR;
     const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
     CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
-    
-    clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
+
+    clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
+                          nullptr);
     clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
-                               &ResultColumn, 0);
+                          &ResultColumn, nullptr);
     SearchFileName = clang_getFileName(SearchFile);
     ResultFileName = clang_getFileName(ResultFile);
     KindSpelling = clang_getCursorKindSpelling(Result.kind);
@@ -4093,7 +4174,7 @@
       CXFile DefinitionFile;
       unsigned DefinitionLine, DefinitionColumn;
       clang_getFileLocation(DefinitionLoc, &DefinitionFile,
-                                 &DefinitionLine, &DefinitionColumn, 0);
+                            &DefinitionLine, &DefinitionColumn, nullptr);
       CXString DefinitionFileName = clang_getFileName(DefinitionFile);
       *Log << llvm::format("  -> %s(%s:%d:%d)",
                      clang_getCString(DefinitionKindSpelling),
@@ -4120,9 +4201,9 @@
   // when visiting a DeclStmt currently, the AST should be enhanced to be able
   // to provide that kind of info.
   if (clang_isDeclaration(X.kind))
-    X.data[1] = 0;
+    X.data[1] = nullptr;
   if (clang_isDeclaration(Y.kind))
-    Y.data[1] = 0;
+    Y.data[1] = nullptr;
 
   return X == Y;
 }
@@ -4700,7 +4781,7 @@
   case Decl::CXXConstructor:
   case Decl::CXXDestructor:
   case Decl::CXXConversion: {
-    const FunctionDecl *Def = 0;
+    const FunctionDecl *Def = nullptr;
     if (cast<FunctionDecl>(D)->getBody(Def))
       return MakeCXCursor(Def, TU);
     return clang_getNullCursor();
@@ -4716,7 +4797,7 @@
   }
 
   case Decl::FunctionTemplate: {
-    const FunctionDecl *Def = 0;
+    const FunctionDecl *Def = nullptr;
     if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
       return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
     return clang_getNullCursor();
@@ -5123,10 +5204,10 @@
       CXTok.ptr_data = II;
     } else if (Tok.is(tok::comment)) {
       CXTok.int_data[0] = CXToken_Comment;
-      CXTok.ptr_data = 0;
+      CXTok.ptr_data = nullptr;
     } else {
       CXTok.int_data[0] = CXToken_Punctuation;
-      CXTok.ptr_data = 0;
+      CXTok.ptr_data = nullptr;
     }
     CXTokens.push_back(CXTok);
     previousWasAt = Tok.is(tok::at);
@@ -5140,7 +5221,7 @@
   }
 
   if (Tokens)
-    *Tokens = 0;
+    *Tokens = nullptr;
   if (NumTokens)
     *NumTokens = 0;
 
@@ -5697,7 +5778,7 @@
       if (lexNext(Lex, Tok, NextIdx, NumTokens))
         break;
 
-      MacroInfo *MI = 0;
+      MacroInfo *MI = nullptr;
       if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
         if (lexNext(Lex, Tok, NextIdx, NumTokens))
           break;
@@ -6138,7 +6219,7 @@
  /// function template.
 static const Decl *maybeGetTemplateCursor(const Decl *D) {
   if (!D)
-    return 0;
+    return nullptr;
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
     if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
@@ -6190,8 +6271,8 @@
 
 CXFile clang_getIncludedFile(CXCursor cursor) {
   if (cursor.kind != CXCursor_InclusionDirective)
-    return 0;
-  
+    return nullptr;
+
   const InclusionDirective *ID = getCursorInclusionDirective(cursor);
   return const_cast<FileEntry *>(ID->getFile());
 }
@@ -6329,7 +6410,7 @@
       return ImportD->getImportedModule();
   }
 
-  return 0;
+  return nullptr;
 }
 
 CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
@@ -6354,14 +6435,14 @@
 
 CXFile clang_Module_getASTFile(CXModule CXMod) {
   if (!CXMod)
-    return 0;
+    return nullptr;
   Module *Mod = static_cast<Module*>(CXMod);
   return const_cast<FileEntry *>(Mod->getASTFile());
 }
 
 CXModule clang_Module_getParent(CXModule CXMod) {
   if (!CXMod)
-    return 0;
+    return nullptr;
   Module *Mod = static_cast<Module*>(CXMod);
   return Mod->Parent;
 }
@@ -6405,10 +6486,10 @@
                                       CXModule CXMod, unsigned Index) {
   if (isNotUsableTU(TU)) {
     LOG_BAD_TU(TU);
-    return 0;
+    return nullptr;
   }
   if (!CXMod)
-    return 0;
+    return nullptr;
   Module *Mod = static_cast<Module*>(CXMod);
   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
 
@@ -6416,7 +6497,7 @@
   if (Index < TopHeaders.size())
     return const_cast<FileEntry *>(TopHeaders[Index]);
 
-  return 0;
+  return nullptr;
 }
 
 } // end: extern "C"
@@ -6432,7 +6513,7 @@
 
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
-      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
+      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
   return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
 }
 
@@ -6442,7 +6523,7 @@
 
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
-      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
+      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
   return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
 }
 
@@ -6452,7 +6533,7 @@
   
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
-      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
+      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
   return (Method && Method->isStatic()) ? 1 : 0;
 }
 
@@ -6462,7 +6543,7 @@
   
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
-      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
+      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
   return (Method && Method->isVirtual()) ? 1 : 0;
 }
 } // end: extern "C"
@@ -6550,7 +6631,7 @@
 CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
   if (isNotUsableTU(TU)) {
     LOG_BAD_TU(TU);
-    CXTUResourceUsage usage = { (void*) 0, 0, 0 };
+    CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
     return usage;
   }
   
@@ -6577,7 +6658,7 @@
   // How much memory is used for caching global code completion results?
   unsigned long completionBytes = 0;
   if (GlobalCodeCompletionAllocator *completionAllocator =
-      astUnit->getCachedCompletionAllocator().getPtr()) {
+      astUnit->getCachedCompletionAllocator().get()) {
     completionBytes = completionAllocator->getTotalMemory();
   }
   createCXTUResourceUsageEntry(*entries,
@@ -6632,10 +6713,10 @@
   createCXTUResourceUsageEntry(*entries,
                                CXTUResourceUsage_Preprocessor_HeaderSearch,
                                pp.getHeaderSearchInfo().getTotalMemory());
-  
+
   CXTUResourceUsage usage = { (void*) entries.get(),
                             (unsigned) entries->size(),
-                            entries->size() ? &(*entries)[0] : 0 };
+                            entries->size() ? &(*entries)[0] : nullptr };
   entries.release();
   return usage;
 }
@@ -6648,7 +6729,7 @@
 CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
   CXSourceRangeList *skipped = new CXSourceRangeList;
   skipped->count = 0;
-  skipped->ranges = 0;
+  skipped->ranges = nullptr;
 
   if (isNotUsableTU(TU)) {
     LOG_BAD_TU(TU);
@@ -6736,8 +6817,7 @@
   if (getenv("LIBCLANG_BGPRIO_DISABLE"))
     return;
 
-  // FIXME: Move to llvm/Support and make it cross-platform.
-#ifdef __APPLE__
+#ifdef USE_DARWIN_THREADS
   setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
 #endif
 }
@@ -6767,9 +6847,9 @@
                                  SourceLocation MacroDefLoc,
                                  CXTranslationUnit TU){
   if (MacroDefLoc.isInvalid() || !TU)
-    return 0;
+    return nullptr;
   if (!II.hadMacroDefinition())
-    return 0;
+    return nullptr;
 
   ASTUnit *Unit = cxtu::getASTUnit(TU);
   Preprocessor &PP = Unit->getPreprocessor();
@@ -6782,16 +6862,16 @@
     }
   }
 
-  return 0;
+  return nullptr;
 }
 
 const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
                                        CXTranslationUnit TU) {
   if (!MacroDef || !TU)
-    return 0;
+    return nullptr;
   const IdentifierInfo *II = MacroDef->getName();
   if (!II)
-    return 0;
+    return nullptr;
 
   return getMacroInfo(*II, MacroDef->getLocation(), TU);
 }
@@ -6800,12 +6880,12 @@
                                                          const Token &Tok,
                                                          CXTranslationUnit TU) {
   if (!MI || !TU)
-    return 0;
+    return nullptr;
   if (Tok.isNot(tok::raw_identifier))
-    return 0;
+    return nullptr;
 
   if (MI->getNumTokens() == 0)
-    return 0;
+    return nullptr;
   SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
                        MI->getDefinitionEndLoc());
   ASTUnit *Unit = cxtu::getASTUnit(TU);
@@ -6813,26 +6893,26 @@
   // Check that the token is inside the definition and not its argument list.
   SourceManager &SM = Unit->getSourceManager();
   if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
-    return 0;
+    return nullptr;
   if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
-    return 0;
+    return nullptr;
 
   Preprocessor &PP = Unit->getPreprocessor();
   PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
   if (!PPRec)
-    return 0;
+    return nullptr;
 
   IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
   if (!II.hadMacroDefinition())
-    return 0;
+    return nullptr;
 
   // Check that the identifier is not one of the macro arguments.
   if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
-    return 0;
+    return nullptr;
 
   MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
   if (!InnerMD)
-    return 0;
+    return nullptr;
 
   return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
 }
@@ -6841,18 +6921,18 @@
                                                          SourceLocation Loc,
                                                          CXTranslationUnit TU) {
   if (Loc.isInvalid() || !MI || !TU)
-    return 0;
+    return nullptr;
 
   if (MI->getNumTokens() == 0)
-    return 0;
+    return nullptr;
   ASTUnit *Unit = cxtu::getASTUnit(TU);
   Preprocessor &PP = Unit->getPreprocessor();
   if (!PP.getPreprocessingRecord())
-    return 0;
+    return nullptr;
   Loc = Unit->getSourceManager().getSpellingLoc(Loc);
   Token Tok;
   if (PP.getRawToken(Loc, Tok))
-    return 0;
+    return nullptr;
 
   return checkForMacroInMacroDefinition(MI, Tok, TU);
 }
@@ -6894,7 +6974,7 @@
 Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
   CXFile File;
   unsigned Line, Column;
-  clang_getFileLocation(Loc, &File, &Line, &Column, 0);
+  clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
   CXString FileName = clang_getFileName(File);
   *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
   clang_disposeString(FileName);
@@ -6907,11 +6987,11 @@
 
   CXFile BFile;
   unsigned BLine, BColumn;
-  clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
+  clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
 
   CXFile EFile;
   unsigned ELine, EColumn;
-  clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
+  clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
 
   CXString BFileName = clang_getFileName(BFile);
   if (BFile == EFile) {
@@ -6939,18 +7019,20 @@
   return *this;
 }
 
+static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
+
 cxindex::Logger::~Logger() {
   LogOS.flush();
 
-  llvm::sys::ScopedLock L(EnableMultithreadingMutex);
+  llvm::sys::ScopedLock L(*LoggingMutex);
 
   static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
 
   raw_ostream &OS = llvm::errs();
   OS << "[libclang:" << Name << ':';
 
-  // FIXME: Portability.
-#if HAVE_PTHREAD_H && __APPLE__
+#ifdef USE_DARWIN_THREADS
+  // TODO: Portability.
   mach_port_t tid = pthread_mach_thread_np(pthread_self());
   OS << tid << ':';
 #endif
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index a3d2364..78e89d9 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -89,8 +89,8 @@
   const Decl *D = getCursorDecl(C);
   if (!D)
     return clang_getNullCursor();
-  
-  Decl *Template = 0;
+
+  Decl *Template = nullptr;
   if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
     if (const ClassTemplatePartialSpecializationDecl *PartialSpec
           = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index dbf54a1..0d88003 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -153,7 +153,7 @@
                                          unsigned chunk_number) {
   CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
   if (!CCStr || chunk_number >= CCStr->size())
-    return 0;
+    return nullptr;
 
   switch ((*CCStr)[chunk_number].Kind) {
   case CodeCompletionString::CK_TypedText:
@@ -176,7 +176,7 @@
   case CodeCompletionString::CK_Equal:
   case CodeCompletionString::CK_HorizontalSpace:
   case CodeCompletionString::CK_VerticalSpace:
-    return 0;
+    return nullptr;
 
   case CodeCompletionString::CK_Optional:
     // Note: treated as an empty text block.
@@ -568,8 +568,8 @@
       }
       
       QualType baseType = Context.getBaseType();
-      NamedDecl *D = NULL;
-      
+      NamedDecl *D = nullptr;
+
       if (!baseType.isNull()) {
         // Get the declaration for a class/struct/union/enum type
         if (const TagType *Tag = baseType->getAs<TagType>())
@@ -587,8 +587,8 @@
                  baseType->getAs<InjectedClassNameType>())
           D = Injected->getDecl();
       }
-      
-      if (D != NULL) {
+
+      if (D != nullptr) {
         CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
 
         AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
@@ -598,7 +598,7 @@
         clang_disposeString(CursorUSR);
 
         const Type *type = baseType.getTypePtrOrNull();
-        if (type != NULL) {
+        if (type) {
           AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
         }
         else {
@@ -651,8 +651,7 @@
   const char *complete_filename;
   unsigned complete_line;
   unsigned complete_column;
-  struct CXUnsavedFile *unsaved_files;
-  unsigned num_unsaved_files;
+  ArrayRef<CXUnsavedFile> unsaved_files;
   unsigned options;
   CXCodeCompleteResults *result;
 };
@@ -662,11 +661,9 @@
   const char *complete_filename = CCAI->complete_filename;
   unsigned complete_line = CCAI->complete_line;
   unsigned complete_column = CCAI->complete_column;
-  struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
-  unsigned num_unsaved_files = CCAI->num_unsaved_files;
   unsigned options = CCAI->options;
   bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
-  CCAI->result = 0;
+  CCAI->result = nullptr;
 
 #ifdef UDP_CODE_COMPLETION_LOGGER
 #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
@@ -674,7 +671,7 @@
 #endif
 #endif
 
-  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
+  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;
 
   if (cxtu::isNotUsableTU(TU)) {
     LOG_BAD_TU(TU);
@@ -693,14 +690,13 @@
 
   // Perform the remapping of source files.
   SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
-                                           Buffer));
+
+  for (auto &UF : CCAI->unsaved_files) {
+    llvm::MemoryBuffer *MB =
+        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+    RemappedFiles.push_back(std::make_pair(UF.Filename, MB));
   }
-  
+
   if (EnableLogging) {
     // FIXME: Add logging.
   }
@@ -708,7 +704,7 @@
   // Parse the resulting source file to find code-completion results.
   AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
       &AST->getFileManager());
-  Results->Results = 0;
+  Results->Results = nullptr;
   Results->NumResults = 0;
   
   // Create a code-completion consumer to capture the results.
@@ -823,9 +819,12 @@
          << complete_filename << ':' << complete_line << ':' << complete_column;
   }
 
-  CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
-                              complete_column, unsaved_files, num_unsaved_files,
-                              options, 0 };
+  if (num_unsaved_files && !unsaved_files)
+    return nullptr;
+
+  CodeCompleteAtInfo CCAI = {TU, complete_filename, complete_line,
+    complete_column, llvm::makeArrayRef(unsaved_files, num_unsaved_files),
+    options, nullptr};
 
   if (getenv("LIBCLANG_NOTHREADS")) {
     clang_codeCompleteAt_Impl(&CCAI);
@@ -837,7 +836,7 @@
   if (!RunSafely(CRC, clang_codeCompleteAt_Impl, &CCAI)) {
     fprintf(stderr, "libclang: crash detected in code completion\n");
     cxtu::getASTUnit(TU)->setUnsafeToFree(true);
-    return 0;
+    return nullptr;
   } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
     PrintLibclangResourceUsage(TU);
 
@@ -873,7 +872,7 @@
   AllocatedCXCodeCompleteResults *Results
     = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
   if (!Results || Index >= Results->Diagnostics.size())
-    return 0;
+    return nullptr;
 
   CXStoredDiagnostic *Diag = Results->DiagnosticsWrappers[Index];
   if (!Diag)
@@ -899,8 +898,8 @@
     static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
   if (!Results)
     return CXCursor_InvalidCode;
-  
-  if (IsIncomplete != NULL) {
+
+  if (IsIncomplete != nullptr) {
     *IsIncomplete = Results->ContainerIsIncomplete;
   }
   
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 8a57d7d..cb977ec 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -186,7 +186,7 @@
       // Diagnostics in the ASTUnit were updated, reset the associated
       // diagnostics.
       delete Set;
-      TU->Diagnostics = 0;
+      TU->Diagnostics = nullptr;
     }
   }
 
@@ -223,16 +223,16 @@
 CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
   if (cxtu::isNotUsableTU(Unit)) {
     LOG_BAD_TU(Unit);
-    return 0;
+    return nullptr;
   }
 
   CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
   if (!D)
-    return 0;
+    return nullptr;
 
   CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
   if (Index >= Diags->getNumDiagnostics())
-    return 0;
+    return nullptr;
 
   return Diags->getDiagnostic(Index);
 }
@@ -240,10 +240,10 @@
 CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
   if (cxtu::isNotUsableTU(Unit)) {
     LOG_BAD_TU(Unit);
-    return 0;
+    return nullptr;
   }
   if (!cxtu::getASTUnit(Unit))
-    return 0;
+    return nullptr;
   return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
 }
 
@@ -267,7 +267,7 @@
     CXFile File;
     unsigned Line, Column;
     clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
-                              &File, &Line, &Column, 0);
+                              &File, &Line, &Column, nullptr);
     if (File) {
       CXString FName = clang_getFileName(File);
       Out << clang_getCString(FName) << ":" << Line << ":";
@@ -285,10 +285,10 @@
           unsigned StartLine, StartColumn, EndLine, EndColumn;
           clang_getSpellingLocation(clang_getRangeStart(Range),
                                     &StartFile, &StartLine, &StartColumn,
-                                    0);
+                                    nullptr);
           clang_getSpellingLocation(clang_getRangeEnd(Range),
-                                    &EndFile, &EndLine, &EndColumn, 0);
-          
+                                    &EndFile, &EndLine, &EndColumn, nullptr);
+
           if (StartFile != EndFile || StartFile != File)
             continue;
           
@@ -326,7 +326,7 @@
     bool NeedComma = false;
 
     if (Options & CXDiagnostic_DisplayOption) {
-      CXString OptionName = clang_getDiagnosticOption(Diagnostic, 0);
+      CXString OptionName = clang_getDiagnosticOption(Diagnostic, nullptr);
       if (const char *OptionText = clang_getCString(OptionName)) {
         if (OptionText[0]) {
           Out << " [" << OptionText;
@@ -464,15 +464,15 @@
   if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
     if (Index < D->getNumDiagnostics())
       return D->getDiagnostic(Index);
-  return 0;  
+  return nullptr;
 }
   
 CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
   if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
     CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
-    return ChildDiags.empty() ? 0 : (CXDiagnosticSet) &ChildDiags;
+    return ChildDiags.empty() ? nullptr : (CXDiagnosticSet) &ChildDiags;
   }
-  return 0;
+  return nullptr;
 }
 
 unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index 322f723..d2baa13 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -78,7 +78,7 @@
   /// itself, so both 'C' can be highlighted.
   const Decl *getCanonical(const Decl *D) const {
     if (!D)
-      return 0;
+      return nullptr;
 
     D = D->getCanonicalDecl();
 
@@ -265,7 +265,7 @@
 static enum CXChildVisitResult findFileMacroRefVisit(CXCursor cursor,
                                                      CXCursor parent,
                                                      CXClientData client_data) {
-  const IdentifierInfo *Macro = 0;
+  const IdentifierInfo *Macro = nullptr;
   if (cursor.kind == CXCursor_MacroDefinition)
     Macro = getCursorMacroDefinition(cursor)->getName();
   else if (cursor.kind == CXCursor_MacroExpansion)
@@ -317,7 +317,7 @@
   SourceManager &SM = Unit->getSourceManager();
 
   FileID FID = SM.translateFile(File);
-  const IdentifierInfo *Macro = 0;
+  const IdentifierInfo *Macro = nullptr;
   if (Cursor.kind == CXCursor_MacroDefinition)
     Macro = getCursorMacroDefinition(Cursor)->getName();
   else
@@ -522,7 +522,7 @@
                                              CXFile file,
                                            CXCursorAndRangeVisitorBlock block) {
   CXCursorAndRangeVisitor visitor = { block,
-                                      block ? _visitCursorAndRange : 0 };
+                                      block ? _visitCursorAndRange : nullptr };
   return clang_findReferencesInFile(cursor, file, visitor);
 }
 
@@ -530,7 +530,7 @@
                                            CXFile file,
                                            CXCursorAndRangeVisitorBlock block) {
   CXCursorAndRangeVisitor visitor = { block,
-                                      block ? _visitCursorAndRange : 0 };
+                                      block ? _visitCursorAndRange : nullptr };
   return clang_findIncludesInFile(TU, file, visitor);
 }
 
diff --git a/tools/libclang/CLog.h b/tools/libclang/CLog.h
index fe6c218..e7419b7 100644
--- a/tools/libclang/CLog.h
+++ b/tools/libclang/CLog.h
@@ -48,7 +48,7 @@
     static const char *sCachedVar = ::getenv("LIBCLANG_LOGGING");
     return sCachedVar;
   }
-  static bool isLoggingEnabled() { return getEnvVar() != 0; }
+  static bool isLoggingEnabled() { return getEnvVar() != nullptr; }
   static bool isStackTracingEnabled() {
     if (const char *EnvOpt = Logger::getEnvVar())
       return llvm::StringRef(EnvOpt) == "2";
@@ -58,7 +58,7 @@
                      bool trace = isStackTracingEnabled()) {
     if (isLoggingEnabled())
       return new Logger(name, trace);
-    return 0;
+    return nullptr;
   }
 
   explicit Logger(llvm::StringRef name, bool trace)
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index 8fb7c0a..4547031 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -33,11 +33,11 @@
   using namespace clang::cxcursor;
 
   if (!clang_isDeclaration(C.kind))
-    return createCXComment(NULL, NULL);
+    return createCXComment(nullptr, nullptr);
 
   const Decl *D = getCursorDecl(C);
   const ASTContext &Context = getCursorContext(C);
-  const FullComment *FC = Context.getCommentForDecl(D, /*PP=*/NULL);
+  const FullComment *FC = Context.getCommentForDecl(D, /*PP=*/nullptr);
 
   return createCXComment(FC, getCursorTU(C));
 }
@@ -101,7 +101,7 @@
 CXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
   const Comment *C = getASTNode(CXC);
   if (!C || ChildIdx >= C->child_count())
-    return createCXComment(NULL, NULL);
+    return createCXComment(nullptr, nullptr);
 
   return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit);
 }
@@ -253,7 +253,7 @@
 CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
   const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
   if (!BCC)
-    return createCXComment(NULL, NULL);
+    return createCXComment(nullptr, nullptr);
 
   return createCXComment(BCC->getParagraph(), CXC.TranslationUnit);
 }
diff --git a/tools/libclang/CXComment.h b/tools/libclang/CXComment.h
index 606ee26..d9d2bde 100644
--- a/tools/libclang/CXComment.h
+++ b/tools/libclang/CXComment.h
@@ -44,7 +44,7 @@
 static inline const T *getASTNodeAs(CXComment CXC) {
   const comments::Comment *C = getASTNode(CXC);
   if (!C)
-    return NULL;
+    return nullptr;
 
   return dyn_cast<T>(C);
 }
diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp
index f4728fe..51677e7 100644
--- a/tools/libclang/CXCompilationDatabase.cpp
+++ b/tools/libclang/CXCompilationDatabase.cpp
@@ -54,7 +54,7 @@
       return new AllocatedCXCompileCommands(std::move(CCmd));
   }
 
-  return 0;
+  return nullptr;
 }
 
 CXCompileCommands
@@ -65,7 +65,7 @@
       return new AllocatedCXCompileCommands(std::move(CCmd));
   }
 
-  return 0;
+  return nullptr;
 }
 
 void
@@ -90,13 +90,13 @@
 clang_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
 {
   if (!Cmds)
-    return 0;
+    return nullptr;
 
   AllocatedCXCompileCommands *ACC =
     static_cast<AllocatedCXCompileCommands *>(Cmds);
 
   if (I >= ACC->CCmd.size())
-    return 0;
+    return nullptr;
 
   return &ACC->CCmd[I];
 }
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index fb4ce66..48f3480 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -34,7 +34,7 @@
 
 CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU) {
   assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
-  CXCursor C = { K, 0, { 0, 0, TU } };
+  CXCursor C = { K, 0, { nullptr, nullptr, TU } };
   return C;
 }
 
@@ -53,6 +53,10 @@
     case attr::Pure: return CXCursor_PureAttr;
     case attr::Const: return CXCursor_ConstAttr;
     case attr::NoDuplicate: return CXCursor_NoDuplicateAttr;
+    case attr::CUDAConstant: return CXCursor_CUDAConstantAttr;
+    case attr::CUDADevice: return CXCursor_CUDADeviceAttr;
+    case attr::CUDAGlobal: return CXCursor_CUDAGlobalAttr;
+    case attr::CUDAHost: return CXCursor_CUDAHostAttr;
   }
 
   return CXCursor_UnexposedAttr;
@@ -211,6 +215,10 @@
   case Stmt::SEHFinallyStmtClass:
     K = CXCursor_SEHFinallyStmt;
     break;
+
+  case Stmt::SEHLeaveStmtClass:
+    K = CXCursor_SEHLeaveStmt;
+    break;
   
   case Stmt::ArrayTypeTraitExprClass:
   case Stmt::AsTypeExprClass:
@@ -515,6 +523,24 @@
   case Stmt::OMPSimdDirectiveClass:
     K = CXCursor_OMPSimdDirective;
     break;
+  case Stmt::OMPForDirectiveClass:
+    K = CXCursor_OMPForDirective;
+    break;
+  case Stmt::OMPSectionsDirectiveClass:
+    K = CXCursor_OMPSectionsDirective;
+    break;
+  case Stmt::OMPSectionDirectiveClass:
+    K = CXCursor_OMPSectionDirective;
+    break;
+  case Stmt::OMPSingleDirectiveClass:
+    K = CXCursor_OMPSingleDirective;
+    break;
+  case Stmt::OMPParallelForDirectiveClass:
+    K = CXCursor_OMPParallelForDirective;
+    break;
+  case Stmt::OMPParallelSectionsDirectiveClass:
+    K = CXCursor_OMPParallelSectionsDirective;
+    break;
   }
 
   CXCursor C = { K, 0, { Parent, S, TU } };
@@ -655,7 +681,7 @@
 
 CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
                                               CXTranslationUnit TU){
-  CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, 0, TU } };
+  CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, nullptr, TU } };
   return C;  
 }
 
@@ -684,7 +710,7 @@
 
 CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinition *MI,
                                              CXTranslationUnit TU) {
-  CXCursor C = { CXCursor_MacroDefinition, 0, { MI, 0, TU } };
+  CXCursor C = { CXCursor_MacroDefinition, 0, { MI, nullptr, TU } };
   return C;
 }
 
@@ -695,7 +721,7 @@
 
 CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI, 
                                             CXTranslationUnit TU) {
-  CXCursor C = { CXCursor_MacroExpansion, 0, { MI, 0, TU } };
+  CXCursor C = { CXCursor_MacroExpansion, 0, { MI, nullptr, TU } };
   return C;
 }
 
@@ -725,7 +751,7 @@
 
 CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID, 
                                                 CXTranslationUnit TU) {
-  CXCursor C = { CXCursor_InclusionDirective, 0, { ID, 0, TU } };
+  CXCursor C = { CXCursor_InclusionDirective, 0, { ID, nullptr, TU } };
   return C;
 }
 
@@ -808,7 +834,7 @@
   if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
       Cursor.kind == CXCursor_ObjCProtocolRef ||
       Cursor.kind == CXCursor_ObjCClassRef)
-    return 0;
+    return nullptr;
 
   return static_cast<const Stmt *>(Cursor.data[1]);
 }
@@ -828,7 +854,7 @@
 ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
   CXTranslationUnit TU = getCursorTU(Cursor);
   if (!TU)
-    return 0;
+    return nullptr;
   return cxtu::getASTUnit(TU);
 }
 
@@ -902,7 +928,7 @@
     return cursor;
 
   const Expr *E = getCursorExpr(cursor);
-  TypeSourceInfo *Type = 0;
+  TypeSourceInfo *Type = nullptr;
   if (const CXXUnresolvedConstructExpr *
         UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
     Type = UnCtor->getTypeSourceInfo();
@@ -985,11 +1011,11 @@
     const Decl *D = cxcursor::getCursorDecl(C);
     if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
       if (i < MD->param_size())
-        return cxcursor::MakeCXCursor(MD->param_begin()[i],
+        return cxcursor::MakeCXCursor(MD->parameters()[i],
                                       cxcursor::getCursorTU(C));
     } else if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
       if (i < FD->param_size())
-        return cxcursor::MakeCXCursor(FD->param_begin()[i],
+        return cxcursor::MakeCXCursor(FD->parameters()[i],
                                       cxcursor::getCursorTU(C));
     }
   }
@@ -1103,7 +1129,7 @@
                                  false);
     return String;
   }
-  return NULL;
+  return nullptr;
 }
 } // end: extern C.
 
@@ -1135,7 +1161,7 @@
                                 CXCursor **overridden,
                                 unsigned *num_overridden) {
   if (overridden)
-    *overridden = 0;
+    *overridden = nullptr;
   if (num_overridden)
     *num_overridden = 0;
   
@@ -1149,9 +1175,9 @@
     
   OverridenCursorsPool &pool =
     *static_cast<OverridenCursorsPool*>(TU->OverridenCursorsPool);
-  
-  OverridenCursorsPool::CursorVec *Vec = 0;
-  
+
+  OverridenCursorsPool::CursorVec *Vec = nullptr;
+
   if (!pool.AvailableCursors.empty()) {
     Vec = pool.AvailableCursors.back();
     pool.AvailableCursors.pop_back();
@@ -1209,7 +1235,7 @@
 }
 
 int clang_Cursor_isDynamicCall(CXCursor C) {
-  const Expr *E = 0;
+  const Expr *E = nullptr;
   if (clang_isExpression(C.kind))
     E = getCursorExpr(C);
   if (!E)
@@ -1218,7 +1244,7 @@
   if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E))
     return MsgE->getReceiverKind() == ObjCMessageExpr::Instance;
 
-  const MemberExpr *ME = 0;
+  const MemberExpr *ME = nullptr;
   if (isa<MemberExpr>(E))
     ME = cast<MemberExpr>(E);
   else if (const CallExpr *CE = dyn_cast<CallExpr>(E))
@@ -1235,7 +1261,7 @@
 
 CXType clang_Cursor_getReceiverType(CXCursor C) {
   CXTranslationUnit TU = cxcursor::getCursorTU(C);
-  const Expr *E = 0;
+  const Expr *E = nullptr;
   if (clang_isExpression(C.kind))
     E = getCursorExpr(C);
 
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 957d519..fee3bac 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -56,7 +56,7 @@
 CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent,
                       CXTranslationUnit TU,
                       SourceRange RegionOfInterest = SourceRange());
-CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = 0);
+CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr);
 
 /// \brief Create an Objective-C superclass reference at the given location.
 CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, 
@@ -172,7 +172,7 @@
   CXCursor C;
 
   bool isPseudo() const {
-    return C.data[1] != 0;
+    return C.data[1] != nullptr;
   }
   const MacroDefinition *getAsMacroDefinition() const {
     assert(isPseudo());
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index 8385f24..ddf3749 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -92,7 +92,7 @@
   // is a persistent diagnostic.
   uintptr_t V = (uintptr_t) DLoc;
   V |= 0x1;
-  CXSourceLocation Loc = { {  (void*) V, 0 }, 0 };
+  CXSourceLocation Loc = { {  (void*) V, nullptr }, 0 };
   return Loc;
 }  
 
@@ -265,7 +265,7 @@
 
   if (!Buffer) {
     reportBad(CXLoadDiag_CannotLoad, ErrStr);
-    return 0;
+    return nullptr;
   }
 
   llvm::BitstreamReader StreamFile;
@@ -282,7 +282,7 @@
       Stream.Read(8) != 'G') {
     reportBad(CXLoadDiag_InvalidFile,
               "Bad header in diagnostics file");
-    return 0;
+    return nullptr;
   }
 
   std::unique_ptr<CXLoadedDiagnosticSetImpl> Diags(
@@ -296,7 +296,7 @@
       case Read_EndOfStream:
         return (CXDiagnosticSet)Diags.release();
       case Read_Failure:
-        return 0;
+        return nullptr;
       case Read_Record:
         llvm_unreachable("Top-level does not have records");
       case Read_BlockEnd:
@@ -308,16 +308,16 @@
     switch (BlockID) {
       case serialized_diags::BLOCK_META:
         if (readMetaBlock(Stream))
-          return 0;
+          return nullptr;
         break;
       case serialized_diags::BLOCK_DIAG:
         if (readDiagnosticBlock(Stream, *Diags.get(), *Diags.get()))
-          return 0;
+          return nullptr;
         break;
       default:
         if (!Stream.SkipBlock()) {
           reportInvalidFile("Malformed block at top-level of diagnostics file");
-          return 0;
+          return nullptr;
         }
         break;
     }
@@ -495,7 +495,7 @@
   unsigned fileID = Record[offset++];
   if (fileID == 0) {
     // Sentinel value.
-    Loc.file = 0;
+    Loc.file = nullptr;
     Loc.line = 0;
     Loc.column = 0;
     Loc.offset = 0;
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index f78b687..64a441e 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -41,7 +41,7 @@
 extern "C" {
   
 CXSourceLocation clang_getNullLocation() {
-  CXSourceLocation Result = { { 0, 0 }, 0 };
+  CXSourceLocation Result = { { nullptr, nullptr }, 0 };
   return Result;
 }
 
@@ -52,7 +52,7 @@
 }
 
 CXSourceRange clang_getNullRange() {
-  CXSourceRange Result = { { 0, 0 }, 0, 0 };
+  CXSourceRange Result = { { nullptr, nullptr }, 0, 0 };
   return Result;
 }
 
@@ -89,7 +89,7 @@
 CXSourceLocation clang_getRangeStart(CXSourceRange range) {
   // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
   if ((uintptr_t)range.ptr_data[0] & 0x1) {
-    CXSourceLocation Result = { { range.ptr_data[0], 0 }, 0 };
+    CXSourceLocation Result = { { range.ptr_data[0], nullptr }, 0 };
     return Result;    
   }
   
@@ -101,7 +101,7 @@
 CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
   // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
   if ((uintptr_t)range.ptr_data[0] & 0x1) {
-    CXSourceLocation Result = { { range.ptr_data[1], 0 }, 0 };
+    CXSourceLocation Result = { { range.ptr_data[1], nullptr }, 0 };
     return Result;    
   }
 
@@ -183,7 +183,7 @@
 static void createNullLocation(CXFile *file, unsigned *line,
                                unsigned *column, unsigned *offset) {
   if (file)
-    *file = 0;
+    *file = nullptr;
   if (line)
     *line = 0;
   if (column)
@@ -194,7 +194,7 @@
 }
 
 static void createNullLocation(CXString *filename, unsigned *line,
-                               unsigned *column, unsigned *offset = 0) {
+                               unsigned *column, unsigned *offset = nullptr) {
   if (filename)
     *filename = cxstring::createEmpty();
   if (line)
diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp
index 1523034..dec8ebc 100644
--- a/tools/libclang/CXString.cpp
+++ b/tools/libclang/CXString.cpp
@@ -51,7 +51,7 @@
 
 CXString createNull() {
   CXString Str;
-  Str.data = 0;
+  Str.data = nullptr;
   Str.private_flags = CXS_Unmanaged;
   return Str;
 }
@@ -81,7 +81,11 @@
 
 CXString createRef(StringRef String) {
   // If the string is not nul-terminated, we have to make a copy.
-  // This is doing a one past end read, and should be removed!
+
+  // FIXME: This is doing a one past end read, and should be removed! For memory
+  // we don't manage, the API string can become unterminated at any time outside
+  // our control.
+
   if (!String.empty() && String.data()[String.size()] != 0)
     return createDup(String);
 
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index ac04259..ed3ed4a 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -97,6 +97,10 @@
 bool isManagedByPool(CXString str);
 
 }
+
+static inline StringRef getContents(const CXUnsavedFile &UF) {
+  return StringRef(UF.Contents, UF.Length);
+}
 }
 
 #endif
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index 13183be..d86ed2b 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -42,7 +42,7 @@
 
 static inline ASTUnit *getASTUnit(CXTranslationUnit TU) {
   if (!TU)
-    return 0;
+    return nullptr;
   return TU->TheASTUnit;
 }
 
@@ -72,7 +72,7 @@
 
   CXTranslationUnitImpl *takeTU() {
     CXTranslationUnitImpl *retTU = TU;
-    TU = 0;
+    TU = nullptr;
     return retTU;
   }
 };
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 82c30bf..fe45899 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -120,7 +120,8 @@
   if (TK == CXType_Invalid)
     TK = GetTypeKind(T);
 
-  CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
+  CXType CT = { TK, { TK == CXType_Invalid ? nullptr
+                                           : T.getAsOpaquePtr(), TU } };
   return CT;
 }
 
@@ -386,7 +387,7 @@
   if (!TP)
     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
 
-  Decl *D = 0;
+  Decl *D = nullptr;
 
 try_again:
   switch (TP->getTypeClass()) {
@@ -432,7 +433,7 @@
 }
 
 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
-  const char *s = 0;
+  const char *s = nullptr;
 #define TKIND(X) case CXType_##X: s = ""  #X  ""; break
   switch (K) {
     TKIND(Invalid);
@@ -854,7 +855,7 @@
     if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
       return cxstring::createRef("?");
   } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
-    Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
+    Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr, encoding);
   else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
     Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
   else {
diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h
index 53d864d..c4ec7b6 100644
--- a/tools/libclang/CursorVisitor.h
+++ b/tools/libclang/CursorVisitor.h
@@ -36,8 +36,8 @@
   const void *data[3];
   CXCursor parent;
   Kind K;
-  VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = 0,
-             const void *d3 = 0)
+  VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = nullptr,
+             const void *d3 = nullptr)
     : parent(C), K(k) {
     data[0] = d1;
     data[1] = d2;
@@ -147,7 +147,7 @@
                 bool VisitIncludedPreprocessingEntries = false,
                 SourceRange RegionOfInterest = SourceRange(),
                 bool VisitDeclsOnly = false,
-                PostChildrenVisitorTy PostChildrenVisitor = 0)
+                PostChildrenVisitorTy PostChildrenVisitor = nullptr)
     : TU(TU), AU(cxtu::getASTUnit(TU)),
       Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor),
       ClientData(ClientData),
@@ -155,13 +155,13 @@
       VisitIncludedEntities(VisitIncludedPreprocessingEntries),
       RegionOfInterest(RegionOfInterest),
       VisitDeclsOnly(VisitDeclsOnly),
-      DI_current(0), FileDI_current(0)
+      DI_current(nullptr), FileDI_current(nullptr)
   {
     Parent.kind = CXCursor_NoDeclFound;
-    Parent.data[0] = 0;
-    Parent.data[1] = 0;
-    Parent.data[2] = 0;
-    StmtParent = 0;
+    Parent.data[0] = nullptr;
+    Parent.data[1] = nullptr;
+    Parent.data[2] = nullptr;
+    StmtParent = nullptr;
   }
 
   ~CursorVisitor() {
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index fbec3d7..7dc53a6 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -170,7 +170,7 @@
   if (!S)
     return;
 
-  if (DC == 0)
+  if (!DC)
     DC = Parent->getLexicalDeclContext();
   BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
 }
diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp
index 64052ed..c8cf1d3 100644
--- a/tools/libclang/IndexDecl.cpp
+++ b/tools/libclang/IndexDecl.cpp
@@ -31,7 +31,8 @@
     return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
   }
 
-  void handleDeclarator(const DeclaratorDecl *D, const NamedDecl *Parent = 0) {
+  void handleDeclarator(const DeclaratorDecl *D,
+                        const NamedDecl *Parent = nullptr) {
     if (!Parent) Parent = D;
 
     if (!IndexCtx.shouldIndexFunctionLocalSymbols()) {
@@ -227,7 +228,7 @@
     
     if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
       if (!IvarD->getSynthesize())
-        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), 0,
+        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
                                  D->getDeclContext());
     }
 
diff --git a/tools/libclang/IndexTypeSourceInfo.cpp b/tools/libclang/IndexTypeSourceInfo.cpp
index 4f8d4e5..f13c0af 100644
--- a/tools/libclang/IndexTypeSourceInfo.cpp
+++ b/tools/libclang/IndexTypeSourceInfo.cpp
@@ -108,7 +108,7 @@
   if (TL.isNull())
     return;
 
-  if (DC == 0)
+  if (!DC)
     DC = Parent->getLexicalDeclContext();
   TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
 }
@@ -122,7 +122,7 @@
   if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
     indexNestedNameSpecifierLoc(Prefix, Parent, DC);
 
-  if (DC == 0)
+  if (!DC)
     DC = Parent->getLexicalDeclContext();
   SourceLocation Loc = NNS.getSourceRange().getBegin();
 
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 47ba97b..58af618 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -472,28 +472,17 @@
   const char *source_filename;
   const char *const *command_line_args;
   int num_command_line_args;
-  struct CXUnsavedFile *unsaved_files;
-  unsigned num_unsaved_files;
+  ArrayRef<CXUnsavedFile> unsaved_files;
   CXTranslationUnit *out_TU;
   unsigned TU_options;
-  int result;
-};
-
-struct MemBufferOwner {
-  SmallVector<const llvm::MemoryBuffer *, 8> Buffers;
-  
-  ~MemBufferOwner() {
-    for (SmallVectorImpl<const llvm::MemoryBuffer *>::iterator
-           I = Buffers.begin(), E = Buffers.end(); I != E; ++I)
-      delete *I;
-  }
+  CXErrorCode &result;
 };
 
 } // anonymous namespace
 
 static void clang_indexSourceFile_Impl(void *UserData) {
-  IndexSourceFileInfo *ITUI =
-    static_cast<IndexSourceFileInfo*>(UserData);
+  const IndexSourceFileInfo *ITUI =
+      static_cast<IndexSourceFileInfo *>(UserData);
   CXIndexAction cxIdxAction = ITUI->idxAction;
   CXClientData client_data = ITUI->client_data;
   IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
@@ -502,17 +491,12 @@
   const char *source_filename = ITUI->source_filename;
   const char * const *command_line_args = ITUI->command_line_args;
   int num_command_line_args = ITUI->num_command_line_args;
-  struct CXUnsavedFile *unsaved_files = ITUI->unsaved_files;
-  unsigned num_unsaved_files = ITUI->num_unsaved_files;
   CXTranslationUnit *out_TU  = ITUI->out_TU;
   unsigned TU_options = ITUI->TU_options;
 
-  // Set up the initial return value.
-  ITUI->result = CXError_Failure;
-
   if (out_TU)
-    *out_TU = 0;
-  bool requestedToGetTU = (out_TU != 0);
+    *out_TU = nullptr;
+  bool requestedToGetTU = (out_TU != nullptr);
 
   if (!cxIdxAction) {
     ITUI->result = CXError_InvalidArguments;
@@ -537,7 +521,7 @@
 
   bool CaptureDiagnostics = !Logger::isLoggingEnabled();
 
-  CaptureDiagnosticConsumer *CaptureDiag = 0;
+  CaptureDiagnosticConsumer *CaptureDiag = nullptr;
   if (CaptureDiagnostics)
     CaptureDiag = new CaptureDiagnosticConsumer();
 
@@ -550,7 +534,7 @@
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
   std::unique_ptr<std::vector<const char *>> Args(
       new std::vector<const char *>());
@@ -579,23 +563,23 @@
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation,
     llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> >
-    CInvokCleanup(CInvok.getPtr());
+    CInvokCleanup(CInvok.get());
 
   if (CInvok->getFrontendOpts().Inputs.empty())
     return;
 
-  std::unique_ptr<MemBufferOwner> BufOwner(new MemBufferOwner());
+  typedef SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 8> MemBufferOwner;
+  std::unique_ptr<MemBufferOwner> BufOwner(new MemBufferOwner);
 
   // Recover resources if we crash before exiting this method.
-  llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner>
-    BufOwnerCleanup(BufOwner.get());
+  llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner> BufOwnerCleanup(
+      BufOwner.get());
 
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    CInvok->getPreprocessorOpts().addRemappedFile(unsaved_files[I].Filename, Buffer);
-    BufOwner->Buffers.push_back(Buffer);
+  for (auto &UF : ITUI->unsaved_files) {
+    llvm::MemoryBuffer *MB =
+        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+    BufOwner->push_back(std::unique_ptr<llvm::MemoryBuffer>(MB));
+    CInvok->getPreprocessorOpts().addRemappedFile(UF.Filename, MB);
   }
 
   // Since libclang is primarily used by batch tools dealing with
@@ -607,7 +591,7 @@
   if (index_options & CXIndexOpt_SuppressWarnings)
     CInvok->getDiagnosticOpts().IgnoreWarnings = true;
 
-  ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags,
+  ASTUnit *Unit = ASTUnit::create(CInvok.get(), Diags,
                                   CaptureDiagnostics,
                                   /*UserFilesAreVolatile=*/true);
   if (!Unit) {
@@ -632,7 +616,7 @@
   std::unique_ptr<IndexingFrontendAction> IndexAction;
   IndexAction.reset(new IndexingFrontendAction(client_data, CB,
                                                index_options, CXTU->getTU(),
-                              SkipBodies ? IdxSession->SkipBodyData.get() : 0));
+                        SkipBodies ? IdxSession->SkipBodyData.get() : nullptr));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
@@ -661,7 +645,7 @@
     PPOpts.DetailedRecord = false;
 
   DiagnosticErrorTrap DiagTrap(*Diags);
-  bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags,
+  bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.get(), Diags,
                                                        IndexAction.get(),
                                                        Unit,
                                                        Persistent,
@@ -796,7 +780,7 @@
     IndexCtxCleanup(IndexCtx.get());
 
   std::unique_ptr<IndexingConsumer> IndexConsumer;
-  IndexConsumer.reset(new IndexingConsumer(*IndexCtx, 0));
+  IndexConsumer.reset(new IndexingConsumer(*IndexCtx, nullptr));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<IndexingConsumer>
@@ -814,7 +798,7 @@
   FileManager &FileMgr = Unit->getFileManager();
 
   if (Unit->getOriginalSourceFileName().empty())
-    IndexCtx->enteredMainFile(0);
+    IndexCtx->enteredMainFile(nullptr);
   else
     IndexCtx->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
 
@@ -840,46 +824,46 @@
 const CXIdxObjCContainerDeclInfo *
 clang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const ObjCContainerDeclInfo *
         ContInfo = dyn_cast<ObjCContainerDeclInfo>(DI))
     return &ContInfo->ObjCContDeclInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxObjCInterfaceDeclInfo *
 clang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const ObjCInterfaceDeclInfo *
         InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
     return &InterInfo->ObjCInterDeclInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxObjCCategoryDeclInfo *
 clang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *DInfo){
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const ObjCCategoryDeclInfo *
         CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
     return &CatInfo->ObjCCatDeclInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxObjCProtocolRefListInfo *
 clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   
@@ -894,50 +878,50 @@
   if (const ObjCCategoryDeclInfo *CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
     return CatInfo->ObjCCatDeclInfo.protocols;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxObjCPropertyDeclInfo *
 clang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const ObjCPropertyDeclInfo *PropInfo = dyn_cast<ObjCPropertyDeclInfo>(DI))
     return &PropInfo->ObjCPropDeclInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxIBOutletCollectionAttrInfo *
 clang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *AInfo) {
   if (!AInfo)
-    return 0;
+    return nullptr;
 
   const AttrInfo *DI = static_cast<const AttrInfo *>(AInfo);
   if (const IBOutletCollectionInfo *
         IBInfo = dyn_cast<IBOutletCollectionInfo>(DI))
     return &IBInfo->IBCollInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxCXXClassDeclInfo *
 clang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const CXXClassDeclInfo *ClassInfo = dyn_cast<CXXClassDeclInfo>(DI))
     return &ClassInfo->CXXClassInfo;
 
-  return 0;
+  return nullptr;
 }
 
 CXIdxClientContainer
 clang_index_getClientContainer(const CXIdxContainerInfo *info) {
   if (!info)
-    return 0;
+    return nullptr;
   const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
   return Container->IndexCtx->getClientContainerForDC(Container->DC);
 }
@@ -952,7 +936,7 @@
 
 CXIdxClientEntity clang_index_getClientEntity(const CXIdxEntityInfo *info) {
   if (!info)
-    return 0;
+    return nullptr;
   const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
   return Entity->IndexCtx->getClientEntity(Entity->Dcl);
 }
@@ -992,16 +976,27 @@
       *Log << command_line_args[i] << " ";
   }
 
-  IndexSourceFileInfo ITUI = { idxAction, client_data, index_callbacks,
-                               index_callbacks_size, index_options,
-                               source_filename, command_line_args,
-                               num_command_line_args, unsaved_files,
-                               num_unsaved_files, out_TU, TU_options,
-                               CXError_Failure };
+  if (num_unsaved_files && !unsaved_files)
+    return CXError_InvalidArguments;
+
+  CXErrorCode result = CXError_Failure;
+  IndexSourceFileInfo ITUI = {
+      idxAction,
+      client_data,
+      index_callbacks,
+      index_callbacks_size,
+      index_options,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      llvm::makeArrayRef(unsaved_files, num_unsaved_files),
+      out_TU,
+      TU_options,
+      result};
 
   if (getenv("LIBCLANG_NOTHREADS")) {
     clang_indexSourceFile_Impl(&ITUI);
-    return ITUI.result;
+    return result;
   }
 
   llvm::CrashRecoveryContext CRC;
@@ -1032,8 +1027,8 @@
     if (out_TU)
       PrintLibclangResourceUsage(*out_TU);
   }
-  
-  return ITUI.result;
+
+  return result;
 }
 
 int clang_indexTranslationUnit(CXIndexAction idxAction,
@@ -1072,8 +1067,8 @@
                                     unsigned *line,
                                     unsigned *column,
                                     unsigned *offset) {
-  if (indexFile) *indexFile = 0;
-  if (file)   *file = 0;
+  if (indexFile) *indexFile = nullptr;
+  if (file)   *file = nullptr;
   if (line)   *line = 0;
   if (column) *column = 0;
   if (offset) *offset = 0;
diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp
index 1637843..bf6e172 100644
--- a/tools/libclang/IndexingContext.cpp
+++ b/tools/libclang/IndexingContext.cpp
@@ -30,7 +30,7 @@
     ObjCProtocolDecl *PD = *I;
     ProtEntities.push_back(EntityInfo());
     IdxCtx.getEntityInfo(PD, ProtEntities.back(), SA);
-    CXIdxObjCProtocolRefInfo ProtInfo = { 0,
+    CXIdxObjCProtocolRefInfo ProtInfo = { nullptr,
                                 MakeCursorObjCProtocolRef(PD, Loc, IdxCtx.CXTU),
                                 IdxCtx.getIndexLoc(Loc) };
     ProtInfos.push_back(ProtInfo);
@@ -58,7 +58,7 @@
     ClassInfo = other.ClassInfo;
     IBCollInfo.objcClass = &ClassInfo;
   } else
-    IBCollInfo.objcClass = 0;
+    IBCollInfo.objcClass = nullptr;
 }
 
 AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
@@ -96,7 +96,7 @@
         IBAttr->getInterfaceLoc()->getTypeLoc().getLocStart();
     IBInfo.IBCollInfo.attrInfo = &IBInfo;
     IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(InterfaceLocStart);
-    IBInfo.IBCollInfo.objcClass = 0;
+    IBInfo.IBCollInfo.objcClass = nullptr;
     IBInfo.IBCollInfo.classCursor = clang_getNullCursor();
     QualType Ty = IBAttr->getInterface();
     if (const ObjCObjectType *ObjectTy = Ty->getAs<ObjCObjectType>()) {
@@ -125,7 +125,7 @@
                                    ScratchAlloc &SA) {
   for (const auto &Base : D->bases()) {
     BaseEntities.push_back(EntityInfo());
-    const NamedDecl *BaseD = 0;
+    const NamedDecl *BaseD = nullptr;
     QualType T = Base.getType();
     SourceLocation Loc = getBaseLoc(Base);
 
@@ -140,7 +140,7 @@
 
     if (BaseD)
       IdxCtx.getEntityInfo(BaseD, BaseEntities.back(), SA);
-    CXIdxBaseClassInfo BaseInfo = { 0,
+    CXIdxBaseClassInfo BaseInfo = { nullptr,
                          MakeCursorCXXBaseSpecifier(&Base, IdxCtx.CXTU),
                          IdxCtx.getIndexLoc(Loc) };
     BaseInfos.push_back(BaseInfo);
@@ -227,14 +227,15 @@
 bool IndexingContext::shouldAbort() {
   if (!CB.abortQuery)
     return false;
-  return CB.abortQuery(ClientData, 0);
+  return CB.abortQuery(ClientData, nullptr);
 }
 
 void IndexingContext::enteredMainFile(const FileEntry *File) {
   if (File && CB.enteredMainFile) {
     CXIdxClientFile idxFile =
       CB.enteredMainFile(ClientData,
-                         static_cast<CXFile>(const_cast<FileEntry *>(File)), 0);
+                         static_cast<CXFile>(const_cast<FileEntry *>(File)),
+                         nullptr);
     FileMap[File] = idxFile;
   }
 }
@@ -283,7 +284,7 @@
   CXIdxImportedASTFileInfo Info = {
                                     static_cast<CXFile>(
                                       const_cast<FileEntry *>(File)),
-                                    /*module=*/NULL,
+                                    /*module=*/nullptr,
                                     getIndexLoc(SourceLocation()),
                                     /*isImplicit=*/false
                                   };
@@ -292,9 +293,9 @@
 }
 
 void IndexingContext::startedTranslationUnit() {
-  CXIdxClientContainer idxCont = 0;
+  CXIdxClientContainer idxCont = nullptr;
   if (CB.startedTranslationUnit)
-    idxCont = CB.startedTranslationUnit(ClientData, 0);
+    idxCont = CB.startedTranslationUnit(ClientData, nullptr);
   addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
 }
 
@@ -302,7 +303,7 @@
   if (!CB.diagnostic)
     return;
 
-  CB.diagnostic(ClientData, CXDiagSet, 0);
+  CB.diagnostic(ClientData, CXDiagSet, nullptr);
 }
 
 bool IndexingContext::handleDecl(const NamedDecl *D,
@@ -464,7 +465,8 @@
   ObjCInterfaceDeclInfo InterInfo(D);
   InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
   InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;
-  InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass : 0;
+  InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass
+                                                             : nullptr;
   InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;
 
   return handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
@@ -529,7 +531,7 @@
     CatDInfo.ObjCCatDeclInfo.classCursor =
         MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
   } else {
-    CatDInfo.ObjCCatDeclInfo.objcClass = 0;
+    CatDInfo.ObjCCatDeclInfo.objcClass = nullptr;
     CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
   }
   CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
@@ -559,11 +561,11 @@
     CatDInfo.ObjCCatDeclInfo.classCursor =
         MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
   } else {
-    CatDInfo.ObjCCatDeclInfo.objcClass = 0;
+    CatDInfo.ObjCCatDeclInfo.objcClass = nullptr;
     CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
   }
   CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
-  CatDInfo.ObjCCatDeclInfo.protocols = 0;
+  CatDInfo.ObjCCatDeclInfo.protocols = nullptr;
 
   return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
 }
@@ -587,7 +589,8 @@
 bool IndexingContext::handleSynthesizedObjCProperty(
                                                 const ObjCPropertyImplDecl *D) {
   ObjCPropertyDecl *PD = D->getPropertyDecl();
-  return handleReference(PD, D->getLocation(), getCursor(D), 0, D->getDeclContext());
+  return handleReference(PD, D->getLocation(), getCursor(D), nullptr,
+                         D->getDeclContext());
 }
 
 bool IndexingContext::handleSynthesizedObjCMethod(const ObjCMethodDecl *D,
@@ -611,13 +614,13 @@
     getEntityInfo(Getter, GetterEntity, SA);
     DInfo.ObjCPropDeclInfo.getter = &GetterEntity;
   } else {
-    DInfo.ObjCPropDeclInfo.getter = 0;
+    DInfo.ObjCPropDeclInfo.getter = nullptr;
   }
   if (ObjCMethodDecl *Setter = D->getSetterMethodDecl()) {
     getEntityInfo(Setter, SetterEntity, SA);
     DInfo.ObjCPropDeclInfo.setter = &SetterEntity;
   } else {
-    DInfo.ObjCPropDeclInfo.setter = 0;
+    DInfo.ObjCPropDeclInfo.setter = nullptr;
   }
 
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
@@ -700,7 +703,7 @@
                               Cursor,
                               getIndexLoc(Loc),
                               &RefEntity,
-                              Parent ? &ParentEntity : 0,
+                              Parent ? &ParentEntity : nullptr,
                               &Container };
   CB.indexEntityReference(ClientData, &Info);
   return true;
@@ -712,7 +715,7 @@
   SourceManager &SM = Ctx->getSourceManager();
   SourceLocation FileLoc = SM.getFileLoc(Loc);
   FileID FID = SM.getFileID(FileLoc);
-  return SM.getFileEntryForID(FID) == 0;
+  return SM.getFileEntryForID(FID) == nullptr;
 }
 
 void IndexingContext::addContainerInMap(const DeclContext *DC,
@@ -736,10 +739,10 @@
 
 CXIdxClientEntity IndexingContext::getClientEntity(const Decl *D) const {
   if (!D)
-    return 0;
+    return nullptr;
   EntityMapTy::const_iterator I = EntityMap.find(D);
   if (I == EntityMap.end())
-    return 0;
+    return nullptr;
   return I->second;
 }
 
@@ -848,28 +851,28 @@
 CXIdxClientContainer
 IndexingContext::getClientContainerForDC(const DeclContext *DC) const {
   if (!DC)
-    return 0;
+    return nullptr;
 
   ContainerMapTy::const_iterator I = ContainerMap.find(DC);
   if (I == ContainerMap.end())
-    return 0;
+    return nullptr;
 
   return I->second;
 }
 
 CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
   if (!File)
-    return 0;
+    return nullptr;
 
   FileMapTy::iterator FI = FileMap.find(File);
   if (FI != FileMap.end())
     return FI->second;
 
-  return 0;
+  return nullptr;
 }
 
 CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
-  CXIdxLoc idxLoc =  { {0, 0}, 0 };
+  CXIdxLoc idxLoc =  { {nullptr, nullptr}, 0 };
   if (Loc.isInvalid())
     return idxLoc;
 
@@ -1093,7 +1096,7 @@
     EntityInfo.name = SA.toCStr(II->getName());
 
   } else if (isa<TagDecl>(D) || isa<FieldDecl>(D) || isa<NamespaceDecl>(D)) {
-    EntityInfo.name = 0; // anonymous tag/field/namespace.
+    EntityInfo.name = nullptr; // anonymous tag/field/namespace.
 
   } else {
     SmallString<256> StrBuf;
@@ -1108,7 +1111,7 @@
     SmallString<512> StrBuf;
     bool Ignore = getDeclCursorUSR(D, StrBuf);
     if (Ignore) {
-      EntityInfo.USR = 0;
+      EntityInfo.USR = nullptr;
     } else {
       EntityInfo.USR = SA.copyCStr(StrBuf.str());
     }
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index 88d623f..c3851cd 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -49,8 +49,8 @@
   IntrusiveRefCntPtr<AttrListInfo> AttrList;
 
   EntityInfo() {
-    name = USR = 0;
-    attributes = 0;
+    name = USR = nullptr;
+    attributes = nullptr;
     numAttributes = 0;
   }
 };
@@ -86,9 +86,9 @@
     this->isRedeclaration = isRedeclaration;
     this->isDefinition = isDefinition;
     this->isContainer = isContainer;
-    attributes = 0;
+    attributes = nullptr;
     numAttributes = 0;
-    declAsContainer = semanticContainer = lexicalContainer = 0;
+    declAsContainer = semanticContainer = lexicalContainer = nullptr;
     flags = 0;
   }
   DeclInfo(DInfoKind K,
@@ -97,9 +97,9 @@
     this->isRedeclaration = isRedeclaration;
     this->isDefinition = isDefinition;
     this->isContainer = isContainer;
-    attributes = 0;
+    attributes = nullptr;
     numAttributes = 0;
-    declAsContainer = semanticContainer = lexicalContainer = 0;
+    declAsContainer = semanticContainer = lexicalContainer = nullptr;
     flags = 0;
   }
 };
@@ -145,7 +145,7 @@
   ObjCInterfaceDeclInfo(const ObjCInterfaceDecl *D)
     : ObjCContainerDeclInfo(Info_ObjCInterface,
                             /*isForwardRef=*/false,
-                          /*isRedeclaration=*/D->getPreviousDecl() != 0,
+                            /*isRedeclaration=*/D->getPreviousDecl() != nullptr,
                             /*isImplementation=*/false) { }
 
   static bool classof(const DeclInfo *D) {
@@ -224,7 +224,7 @@
   IBOutletCollectionInfo(CXCursor C, CXIdxLoc Loc, const Attr *A) :
     AttrInfo(CXIdxAttr_IBOutletCollection, C, Loc, A) {
     assert(C.kind == CXCursor_IBOutletCollectionAttr);
-    IBCollInfo.objcClass = 0;
+    IBCollInfo.objcClass = nullptr;
   }
 
   IBOutletCollectionInfo(const IBOutletCollectionInfo &other);
@@ -252,7 +252,7 @@
 
   const CXIdxAttrInfo *const *getAttrs() const {
     if (CXAttrs.empty())
-      return 0;
+      return nullptr;
     return CXAttrs.data();
   }
   unsigned getNumAttrs() const { return (unsigned)CXAttrs.size(); }
@@ -333,7 +333,7 @@
 public:
   IndexingContext(CXClientData clientData, IndexerCallbacks &indexCallbacks,
                   unsigned indexOptions, CXTranslationUnit cxTU)
-    : Ctx(0), ClientData(clientData), CB(indexCallbacks),
+    : Ctx(nullptr), ClientData(clientData), CB(indexCallbacks),
       IndexOptions(indexOptions), CXTU(cxTU),
       StrScratch(), StrAdapterCount(0) { }
 
@@ -376,19 +376,19 @@
   void indexTagDecl(const TagDecl *D);
 
   void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
-                           const DeclContext *DC = 0);
+                           const DeclContext *DC = nullptr);
 
   void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
-                    const DeclContext *DC = 0);
+                    const DeclContext *DC = nullptr);
 
   void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
                                    const NamedDecl *Parent,
-                                   const DeclContext *DC = 0);
+                                   const DeclContext *DC = nullptr);
 
   void indexDeclContext(const DeclContext *DC);
   
   void indexBody(const Stmt *S, const NamedDecl *Parent,
-                 const DeclContext *DC = 0);
+                 const DeclContext *DC = nullptr);
 
   void handleDiagnosticSet(CXDiagnosticSet CXDiagSet);
 
@@ -431,13 +431,13 @@
   bool handleReference(const NamedDecl *D, SourceLocation Loc, CXCursor Cursor,
                        const NamedDecl *Parent,
                        const DeclContext *DC,
-                       const Expr *E = 0,
+                       const Expr *E = nullptr,
                        CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
 
   bool handleReference(const NamedDecl *D, SourceLocation Loc,
                        const NamedDecl *Parent,
                        const DeclContext *DC,
-                       const Expr *E = 0,
+                       const Expr *E = nullptr,
                        CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
 
   bool isNotFromSourceFile(SourceLocation Loc) const;
@@ -465,7 +465,7 @@
   bool handleDecl(const NamedDecl *D,
                   SourceLocation Loc, CXCursor Cursor,
                   DeclInfo &DInfo,
-                  const DeclContext *LexicalDC = 0);
+                  const DeclContext *LexicalDC = nullptr);
 
   bool handleObjCContainer(const ObjCContainerDecl *D,
                            SourceLocation Loc, CXCursor Cursor,
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index 7502a42..e66b185 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -206,6 +206,12 @@
   else {
     $NewDir = "$Dir/$DateString-$RunNumber";
   }
+
+  # Make sure that the directory does not exist in order to avoid hijack.
+  if (-e $NewDir) {
+      DieDiag("The directory '$NewDir' already exists.\n");
+  }
+
   mkpath($NewDir);
   return $NewDir;
 }
@@ -368,6 +374,7 @@
 
   my $BugType        = "";
   my $BugFile        = "";
+  my $BugFunction    = "";
   my $BugCategory    = "";
   my $BugDescription = "";
   my $BugPathLength  = 1;
@@ -395,8 +402,13 @@
     elsif (/<!-- BUGDESC (.*) -->$/) {
       $BugDescription = $1;
     }
+    elsif (/<!-- FUNCTIONNAME (.*) -->$/) {
+      $BugFunction = $1;
+    }
+
   }
 
+
   close(IN);
 
   if (!defined $BugCategory) {
@@ -409,7 +421,7 @@
     return;
   }
 
-  push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine,
+  push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugFunction, $BugLine,
                  $BugPathLength ];
 }
 
@@ -498,6 +510,8 @@
 sub FileWanted {
     my $baseDirRegEx = quotemeta $baseDir;
     my $file = $File::Find::name;
+
+    # The name of the file is generated by clang binary (HTMLDiagnostics.cpp)
     if ($file =~ /report-.*\.html$/) {
        my $relative_file = $file;
        $relative_file =~ s/$baseDirRegEx//g;
@@ -699,6 +713,7 @@
   <td>Bug Group</td>
   <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind">&nbsp;&#x25BE;</span></td>
   <td>File</td>
+  <td>Function/Method</td>
   <td class="Q">Line</td>
   <td class="Q">Path Length</td>
   <td class="sorttable_nosort"></td>
@@ -756,13 +771,17 @@
       }
       print OUT "</td>";
 
+      print OUT "<td class=\"DESC\">";
+      print OUT $row->[4];
+      print OUT "</td>";
+
       # Print out the quantities.
-      for my $j ( 4 .. 5 ) {
+      for my $j ( 5 .. 6 ) {
         print OUT "<td class=\"Q\">$row->[$j]</td>";
       }
 
       # Print the rest of the columns.
-      for (my $j = 6; $j <= $#{$row}; ++$j) {
+      for (my $j = 7; $j <= $#{$row}; ++$j) {
         print OUT "<td>$row->[$j]</td>"
       }
 
@@ -1175,6 +1194,13 @@
  -analyzer-config <options>
 
    Provide options to pass through to the analyzer's -analyzer-config flag.
+   Several options are separated with comma: 'key1=val1,key2=val2'
+
+   Available options:
+     * stable-report-filename=true or false (default)
+       Switch the page naming to:
+       report-<filename>-<function/method name>-<id>.html
+       instead of report-XXXXXX.html
 
 CONTROLLING CHECKERS:
 
diff --git a/unittests/AST/ASTVectorTest.cpp b/unittests/AST/ASTVectorTest.cpp
index a92e86b..ce6d0a0 100644
--- a/unittests/AST/ASTVectorTest.cpp
+++ b/unittests/AST/ASTVectorTest.cpp
@@ -18,7 +18,7 @@
 using namespace clang;
 
 LLVM_ATTRIBUTE_UNUSED void CompileTest() {
-  ASTContext *C = 0;
+  ASTContext *C = nullptr;
   ASTVector<int> V;
   V.insert(*C, V.begin(), 0);
 }
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index 9a55626..2fa1078 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -12,6 +12,7 @@
   DeclTest.cpp
   EvaluateAsRValueTest.cpp
   ExternalASTSourceTest.cpp
+  NamedDeclPrinterTest.cpp
   SourceLocationTest.cpp
   StmtPrinterTest.cpp
   )
diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp
index 0064078..ae1410f 100644
--- a/unittests/AST/CommentParser.cpp
+++ b/unittests/AST/CommentParser.cpp
@@ -60,7 +60,7 @@
 
   Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source));
 
-  Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ NULL);
+  Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ nullptr);
   Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
   FullComment *FC = P.parseFullComment();
 
@@ -74,7 +74,7 @@
   if (Tok.is(tok::eof))
     return FC;
   else
-    return NULL;
+    return nullptr;
 }
 
 ::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) {
diff --git a/unittests/AST/NamedDeclPrinterTest.cpp b/unittests/AST/NamedDeclPrinterTest.cpp
new file mode 100644
index 0000000..4823b44
--- /dev/null
+++ b/unittests/AST/NamedDeclPrinterTest.cpp
@@ -0,0 +1,133 @@
+//===- unittests/AST/NamedDeclPrinterTest.cpp --- NamedDecl printer tests -===//
+//
+//                     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 NamedDecl::printQualifiedName().
+//
+// These tests have a coding convention:
+// * declaration to be printed is named 'A' unless it should have some special
+// name (e.g., 'operator+');
+// * additional helper declarations are 'Z', 'Y', 'X' and so on.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+class PrintMatch : public MatchFinder::MatchCallback {
+  SmallString<1024> Printed;
+  unsigned NumFoundDecls;
+  bool SuppressUnwrittenScope;
+
+public:
+  explicit PrintMatch(bool suppressUnwrittenScope)
+    : NumFoundDecls(0), SuppressUnwrittenScope(suppressUnwrittenScope) {}
+
+  virtual void run(const MatchFinder::MatchResult &Result) {
+    const NamedDecl *ND = Result.Nodes.getNodeAs<NamedDecl>("id");
+    if (!ND)
+      return;
+    NumFoundDecls++;
+    if (NumFoundDecls > 1)
+      return;
+
+    llvm::raw_svector_ostream Out(Printed);
+    PrintingPolicy Policy = Result.Context->getPrintingPolicy();
+    Policy.SuppressUnwrittenScope = SuppressUnwrittenScope;
+    ND->printQualifiedName(Out, Policy);
+  }
+
+  StringRef getPrinted() const {
+    return Printed;
+  }
+
+  unsigned getNumFoundDecls() const {
+    return NumFoundDecls;
+  }
+};
+
+::testing::AssertionResult
+PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
+                        bool SuppressUnwrittenScope,
+                        const DeclarationMatcher &NodeMatch,
+                        StringRef ExpectedPrinted, StringRef FileName) {
+  PrintMatch Printer(SuppressUnwrittenScope);
+  MatchFinder Finder;
+  Finder.addMatcher(NodeMatch, &Printer);
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
+
+  if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
+    return testing::AssertionFailure()
+        << "Parsing error in \"" << Code.str() << "\"";
+
+  if (Printer.getNumFoundDecls() == 0)
+    return testing::AssertionFailure()
+        << "Matcher didn't find any named declarations";
+
+  if (Printer.getNumFoundDecls() > 1)
+    return testing::AssertionFailure()
+        << "Matcher should match only one named declaration "
+           "(found " << Printer.getNumFoundDecls() << ")";
+
+  if (Printer.getPrinted() != ExpectedPrinted)
+    return ::testing::AssertionFailure()
+        << "Expected \"" << ExpectedPrinted.str() << "\", "
+           "got \"" << Printer.getPrinted().str() << "\"";
+
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult
+PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,
+                             StringRef ExpectedPrinted) {
+  std::vector<std::string> Args(1, "-std=c++98");
+  return PrintedNamedDeclMatches(Code,
+                                 Args,
+                                 /*SuppressUnwrittenScope*/ false,
+                                 namedDecl(hasName(DeclName)).bind("id"),
+                                 ExpectedPrinted,
+                                 "input.cc");
+}
+
+::testing::AssertionResult
+PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,
+                                    StringRef ExpectedPrinted) {
+  std::vector<std::string> Args(1, "-std=c++11");
+  return PrintedNamedDeclMatches(Code,
+                                 Args,
+                                 /*SuppressUnwrittenScope*/ true,
+                                 namedDecl(hasName(DeclName)).bind("id"),
+                                 ExpectedPrinted,
+                                 "input.cc");
+}
+
+} // unnamed namespace
+
+TEST(NamedDeclPrinter, TestNamespace1) {
+  ASSERT_TRUE(PrintedNamedDeclCXX98Matches(
+    "namespace { int A; }",
+    "A",
+    "(anonymous namespace)::A"));
+}
+
+TEST(NamedDeclPrinter, TestNamespace2) {
+  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
+    "inline namespace Z { namespace { int A; } }",
+    "A",
+    "A"));
+}
diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp
index 6e94442..dc00b86 100644
--- a/unittests/AST/SourceLocationTest.cpp
+++ b/unittests/AST/SourceLocationTest.cpp
@@ -263,6 +263,84 @@
       unresolvedUsingValueDecl()));
 }
 
+TEST(FriendDecl, FriendFunctionLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(2, 13);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend void f();\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendFunctionRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(2, 1, 2, 15);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend void f();\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendClassLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(2, 8);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend class B;\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendClassRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(2, 1, 2, 14);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend class B;\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendTemplateParameterLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(3, 8);
+  EXPECT_TRUE(Verifier.match("template <typename T>\n"
+                             "struct A {\n"
+                             "friend T;\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendTemplateParameterRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(3, 1, 3, 8);
+  EXPECT_TRUE(Verifier.match("template <typename T>\n"
+                             "struct A {\n"
+                             "friend T;\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendDecltypeLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(4, 8);
+  EXPECT_TRUE(Verifier.match("struct A;\n"
+                             "A foo();\n"
+                             "struct A {\n"
+                             "friend decltype(foo());\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendDecltypeRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(4, 1, 4, 8);
+  EXPECT_TRUE(Verifier.match("struct A;\n"
+                             "A foo();\n"
+                             "struct A {\n"
+                             "friend decltype(foo());\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
 TEST(FriendDecl, InstantiationSourceRange) {
   RangeVerifier<FriendDecl> Verifier;
   Verifier.expectRange(4, 3, 4, 35);
diff --git a/unittests/AST/StmtPrinterTest.cpp b/unittests/AST/StmtPrinterTest.cpp
index d726517..541fb3d 100644
--- a/unittests/AST/StmtPrinterTest.cpp
+++ b/unittests/AST/StmtPrinterTest.cpp
@@ -32,8 +32,9 @@
 namespace {
 
 void PrintStmt(raw_ostream &Out, const ASTContext *Context, const Stmt *S) {
+  assert(S != nullptr && "Expected non-null Stmt");
   PrintingPolicy Policy = Context->getPrintingPolicy();
-  S->printPretty(Out, /*Helper*/ 0, Policy);
+  S->printPretty(Out, /*Helper*/ nullptr, Policy);
 }
 
 class PrintMatch : public MatchFinder::MatchCallback {
@@ -133,6 +134,8 @@
                                               StringRef ContainingFunction,
                                               StringRef ExpectedPrinted) {
   std::vector<std::string> Args;
+  Args.push_back("-target");
+  Args.push_back("i686-pc-win32");
   Args.push_back("-std=c++98");
   Args.push_back("-fms-extensions");
   Args.push_back("-Wno-unused-value");
@@ -168,9 +171,9 @@
     "  1i64, -1i64, 1ui64;"
     "}",
     "A",
+    "1i8 , -1i8 , 1Ui8 , "
+    "1i16 , -1i16 , 1Ui16 , "
     "1 , -1 , 1U , "
-    "1 , -1 , 1U , "
-    "1L , -1L , 1UL , "
     "1LL , -1LL , 1ULL"));
     // Should be: with semicolon
 }
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index 691719c..e424acd 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -44,14 +44,15 @@
 
 TEST(Finder, DynamicOnlyAcceptsSomeMatchers) {
   MatchFinder Finder;
-  EXPECT_TRUE(Finder.addDynamicMatcher(decl(), NULL));
-  EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), NULL));
-  EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)), NULL));
+  EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr));
+  EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr));
+  EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)),
+                                       nullptr));
 
   // Do not accept non-toplevel matchers.
-  EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), NULL));
-  EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), NULL));
-  EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), NULL));
+  EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
+  EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), nullptr));
+  EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
 }
 
 TEST(Decl, MatchesDeclarations) {
@@ -697,7 +698,8 @@
         EXPECT_EQ(Nodes->getNodeAs<T>(Id), I->second.get<T>());
       return true;
     }
-    EXPECT_TRUE(M.count(Id) == 0 || M.find(Id)->second.template get<T>() == 0);
+    EXPECT_TRUE(M.count(Id) == 0 ||
+                M.find(Id)->second.template get<T>() == nullptr);
     return false;
   }
 
@@ -1015,6 +1017,17 @@
                          forRangeStmt()));
 }
 
+TEST(Matcher, SubstNonTypeTemplateParm) {
+  EXPECT_FALSE(matches("template<int N>\n"
+                       "struct A {  static const int n = 0; };\n"
+                       "struct B : public A<42> {};",
+                       substNonTypeTemplateParmExpr()));
+  EXPECT_TRUE(matches("template<int N>\n"
+                      "struct A {  static const int n = N; };\n"
+                      "struct B : public A<42> {};",
+                      substNonTypeTemplateParmExpr()));
+}
+
 TEST(Matcher, UserDefinedLiteral) {
   EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
                       "  return i + 1;"
@@ -1165,6 +1178,18 @@
       "}", Reference));
 }
 
+TEST(Matcher, VarDecl_Storage) {
+  auto M = varDecl(hasName("X"), hasLocalStorage());
+  EXPECT_TRUE(matches("void f() { int X; }", M));
+  EXPECT_TRUE(notMatches("int X;", M));
+  EXPECT_TRUE(notMatches("void f() { static int X; }", M));
+
+  M = varDecl(hasName("X"), hasGlobalStorage());
+  EXPECT_TRUE(notMatches("void f() { int X; }", M));
+  EXPECT_TRUE(matches("int X;", M));
+  EXPECT_TRUE(matches("void f() { static int X; }", M));
+}
+
 TEST(Matcher, FindsVarDeclInFunctionParameter) {
   EXPECT_TRUE(matches(
       "void f(int i) {}",
@@ -3609,6 +3634,27 @@
                  compoundStmt(hasParent(recordDecl()))));
 }
 
+TEST(HasParent, NoDuplicateParents) {
+  class HasDuplicateParents : public BoundNodesCallback {
+  public:
+    bool run(const BoundNodes *Nodes) override { return false; }
+    bool run(const BoundNodes *Nodes, ASTContext *Context) override {
+      const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
+      std::set<const void *> Parents;
+      for (const auto &Parent : Context->getParents(*Node)) {
+        if (!Parents.insert(Parent.getMemoizationData()).second) {
+          return true;
+        }
+      }
+      return false;
+    }
+  };
+  EXPECT_FALSE(matchAndVerifyResultTrue(
+      "template <typename T> int Foo() { return 1 + 2; }\n"
+      "int x = Foo<int>() + Foo<unsigned>();",
+      stmt().bind("node"), new HasDuplicateParents()));
+}
+
 TEST(TypeMatching, MatchesTypes) {
   EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
 }
@@ -4104,7 +4150,7 @@
   virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
     const T *Node = Nodes->getNodeAs<T>(Id);
     return selectFirst<const T>(InnerId,
-                                match(InnerMatcher, *Node, *Context)) != NULL;
+                                match(InnerMatcher, *Node, *Context)) !=nullptr;
   }
 private:
   std::string Id;
@@ -4164,7 +4210,7 @@
     return selectFirst<const T>(
                "", match(stmt(hasParent(
                              stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
-                         *Node, Context)) != NULL;
+                         *Node, Context)) != nullptr;
   }
   bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
     // Use the original typed pointer to verify we can pass pointers to subtypes
@@ -4173,7 +4219,7 @@
     return selectFirst<const T>(
                "", match(decl(hasParent(
                              decl(has(decl(equalsNode(TypedNode)))).bind(""))),
-                         *Node, Context)) != NULL;
+                         *Node, Context)) != nullptr;
   }
 };
 
diff --git a/unittests/ASTMatchers/ASTMatchersTest.h b/unittests/ASTMatchers/ASTMatchersTest.h
index 8e243cf..2e4ee2c 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.h
+++ b/unittests/ASTMatchers/ASTMatchersTest.h
@@ -40,7 +40,7 @@
       : Verified(Verified), FindResultReviewer(FindResultVerifier) {}
 
   virtual void run(const MatchFinder::MatchResult &Result) {
-    if (FindResultReviewer != NULL) {
+    if (FindResultReviewer != nullptr) {
       *Verified |= FindResultReviewer->run(&Result.Nodes, Result.Context);
     } else {
       *Verified = true;
@@ -64,9 +64,9 @@
                                               llvm::StringRef CompileArg) {
   bool Found = false, DynamicFound = false;
   MatchFinder Finder;
-  VerifyMatch VerifyFound(0, &Found);
+  VerifyMatch VerifyFound(nullptr, &Found);
   Finder.addMatcher(AMatcher, &VerifyFound);
-  VerifyMatch VerifyDynamicFound(0, &DynamicFound);
+  VerifyMatch VerifyDynamicFound(nullptr, &DynamicFound);
   if (!Finder.addDynamicMatcher(AMatcher, &VerifyDynamicFound))
     return testing::AssertionFailure() << "Could not add dynamic matcher";
   std::unique_ptr<FrontendActionFactory> Factory(
diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
index abacb6f..e659b3a 100644
--- a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -40,7 +40,7 @@
   }
 
   VariantMatcher constructMatcher(StringRef MatcherName,
-                                  Diagnostics *Error = NULL) {
+                                  Diagnostics *Error = nullptr) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
     llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
@@ -53,7 +53,7 @@
 
   VariantMatcher constructMatcher(StringRef MatcherName,
                                   const VariantValue &Arg1,
-                                  Diagnostics *Error = NULL) {
+                                  Diagnostics *Error = nullptr) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
     llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
@@ -67,7 +67,7 @@
   VariantMatcher constructMatcher(StringRef MatcherName,
                                   const VariantValue &Arg1,
                                   const VariantValue &Arg2,
-                                  Diagnostics *Error = NULL) {
+                                  Diagnostics *Error = nullptr) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
     llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
@@ -83,7 +83,7 @@
 
   CompVector getCompletions() {
     return Registry::getCompletions(
-        llvm::ArrayRef<std::pair<MatcherCtor, unsigned> >());
+        ArrayRef<std::pair<MatcherCtor, unsigned> >());
   }
 
   CompVector getCompletions(StringRef MatcherName1, unsigned ArgNo1) {
@@ -110,7 +110,8 @@
   }
 
   bool hasCompletion(const CompVector &Comps, StringRef TypedText,
-                     StringRef MatcherDecl = StringRef(), unsigned *Index = 0) {
+                     StringRef MatcherDecl = StringRef(),
+                     unsigned *Index = nullptr) {
     for (CompVector::const_iterator I = Comps.begin(), E = Comps.end(); I != E;
          ++I) {
       if (I->TypedText == TypedText &&
diff --git a/unittests/Basic/FileManagerTest.cpp b/unittests/Basic/FileManagerTest.cpp
index 9df8532..b3bc767 100644
--- a/unittests/Basic/FileManagerTest.cpp
+++ b/unittests/Basic/FileManagerTest.cpp
@@ -11,7 +11,7 @@
 #include "clang/Basic/FileSystemOptions.h"
 #include "clang/Basic/FileSystemStatCache.h"
 #include "gtest/gtest.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 
 using namespace llvm;
 using namespace clang;
@@ -51,8 +51,9 @@
   }
 
   // Implement FileSystemStatCache::getStat().
-  virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                               vfs::File **F, vfs::FileSystem &FS) {
+  LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override {
     if (StatCalls.count(Path) != 0) {
       Data = StatCalls[Path];
       return CacheExists;
@@ -76,17 +77,17 @@
 // (not NULL, correct name).
 TEST_F(FileManagerTest, getVirtualFileSetsTheDirFieldCorrectly) {
   const FileEntry *file = manager.getVirtualFile("foo.cpp", 42, 0);
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file != nullptr);
 
   const DirectoryEntry *dir = file->getDir();
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ(".", dir->getName());
 
   file = manager.getVirtualFile("x/y/z.cpp", 42, 0);
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file != nullptr);
 
   dir = file->getDir();
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("x/y", dir->getName());
 }
 
@@ -98,9 +99,9 @@
   // by what's in the real file system.
   manager.addStatCache(new FakeStatCache);
 
-  EXPECT_EQ(NULL, manager.getDirectory("virtual/dir/foo"));
-  EXPECT_EQ(NULL, manager.getDirectory("virtual/dir"));
-  EXPECT_EQ(NULL, manager.getDirectory("virtual"));
+  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir/foo"));
+  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir"));
+  EXPECT_EQ(nullptr, manager.getDirectory("virtual"));
 }
 
 // When a virtual file is added, all of its ancestors should be created.
@@ -109,14 +110,14 @@
   manager.addStatCache(new FakeStatCache);
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
-  EXPECT_EQ(NULL, manager.getDirectory("virtual/dir/foo"));
+  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir/foo"));
 
   const DirectoryEntry *dir = manager.getDirectory("virtual/dir");
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("virtual/dir", dir->getName());
 
   dir = manager.getDirectory("virtual");
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("virtual", dir->getName());
 }
 
@@ -137,11 +138,11 @@
   manager.addStatCache(statCache);
 
   const FileEntry *file = manager.getFile("/tmp/test");
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file != nullptr);
   EXPECT_STREQ("/tmp/test", file->getName());
 
   const DirectoryEntry *dir = file->getDir();
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("/tmp", dir->getName());
 
 #ifdef LLVM_ON_WIN32
@@ -161,11 +162,11 @@
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
   const FileEntry *file = manager.getFile("virtual/dir/bar.h");
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file != nullptr);
   EXPECT_STREQ("virtual/dir/bar.h", file->getName());
 
   const DirectoryEntry *dir = file->getDir();
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("virtual/dir", dir->getName());
 }
 
@@ -182,8 +183,8 @@
 
   const FileEntry *fileFoo = manager.getFile("foo.cpp");
   const FileEntry *fileBar = manager.getFile("bar.cpp");
-  ASSERT_TRUE(fileFoo != NULL);
-  ASSERT_TRUE(fileBar != NULL);
+  ASSERT_TRUE(fileFoo != nullptr);
+  ASSERT_TRUE(fileBar != nullptr);
   EXPECT_NE(fileFoo, fileBar);
 }
 
@@ -200,7 +201,7 @@
   manager.getVirtualFile("bar.cpp", 200, 0);
 
   const FileEntry *file = manager.getFile("xyz.txt");
-  EXPECT_EQ(NULL, file);
+  EXPECT_EQ(nullptr, file);
 }
 
 // The following tests apply to Unix-like system only.
diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp
index f227d0d..9ea093c 100644
--- a/unittests/Basic/SourceManagerTest.cpp
+++ b/unittests/Basic/SourceManagerTest.cpp
@@ -20,7 +20,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -38,7 +38,7 @@
       SourceMgr(Diags, FileMgr),
       TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, &*TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
   }
 
   FileSystemOptions FileMgrOpts;
@@ -47,7 +47,7 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> Target;
 };
 
@@ -65,7 +65,7 @@
                          bool Complain) override { }
 
   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
-    { return 0; }
+    { return nullptr; }
   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
     { return 0; };
 };
@@ -83,7 +83,7 @@
                           &*Target);
   Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
                   HeaderInfo, ModLoader,
-                  /*IILookup =*/0,
+                  /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
   PP.EnterMainSourceFile();
@@ -168,7 +168,7 @@
   EXPECT_TRUE(Invalid);
 
   // Test with no invalid flag.
-  EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, NULL));
+  EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, nullptr));
 }
 
 #if defined(LLVM_ON_UNIX)
@@ -200,7 +200,7 @@
                           &*Target);
   Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
                   HeaderInfo, ModLoader,
-                  /*IILookup =*/0,
+                  /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
   PP.EnterMainSourceFile();
@@ -298,7 +298,7 @@
                           &*Target);
   Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
                   HeaderInfo, ModLoader,
-                  /*IILookup =*/0,
+                  /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
 
diff --git a/unittests/Basic/VirtualFileSystemTest.cpp b/unittests/Basic/VirtualFileSystemTest.cpp
index 40d2f16..e7d361e 100644
--- a/unittests/Basic/VirtualFileSystemTest.cpp
+++ b/unittests/Basic/VirtualFileSystemTest.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SourceMgr.h"
@@ -35,20 +36,63 @@
     std::map<std::string, vfs::Status>::iterator I =
         FilesAndDirs.find(Path.str());
     if (I == FilesAndDirs.end())
-      return error_code(errc::no_such_file_or_directory, posix_category());
+      return make_error_code(llvm::errc::no_such_file_or_directory);
     return I->second;
   }
-  error_code openFileForRead(const Twine &Path,
-                             std::unique_ptr<vfs::File> &Result) {
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<vfs::File> &Result) {
     llvm_unreachable("unimplemented");
   }
-  error_code getBufferForFile(const Twine &Name,
-                              std::unique_ptr<MemoryBuffer> &Result,
-                              int64_t FileSize = -1,
-                              bool RequiresNullTerminator = true) {
+  std::error_code getBufferForFile(const Twine &Name,
+                                   std::unique_ptr<MemoryBuffer> &Result,
+                                   int64_t FileSize = -1,
+                                   bool RequiresNullTerminator = true) {
     llvm_unreachable("unimplemented");
   }
 
+  struct DirIterImpl : public clang::vfs::detail::DirIterImpl {
+    std::map<std::string, vfs::Status> &FilesAndDirs;
+    std::map<std::string, vfs::Status>::iterator I;
+    std::string Path;
+    bool isInPath(StringRef S) {
+      if (Path.size() < S.size() && S.find(Path) == 0) {
+        auto LastSep = S.find_last_of('/');
+        if (LastSep == Path.size() || LastSep == Path.size()-1)
+          return true;
+      }
+      return false;
+    }
+    DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs,
+                const Twine &_Path)
+        : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()),
+          Path(_Path.str()) {
+      for ( ; I != FilesAndDirs.end(); ++I) {
+        if (isInPath(I->first)) {
+          CurrentEntry = I->second;
+          break;
+        }
+      }
+    }
+    std::error_code increment() override {
+      ++I;
+      for ( ; I != FilesAndDirs.end(); ++I) {
+        if (isInPath(I->first)) {
+          CurrentEntry = I->second;
+          break;
+        }
+      }
+      if (I == FilesAndDirs.end())
+        CurrentEntry = vfs::Status();
+      return std::error_code();
+    }
+  };
+
+  vfs::directory_iterator dir_begin(const Twine &Dir,
+                                    std::error_code &EC) override {
+    return vfs::directory_iterator(
+        std::make_shared<DirIterImpl>(FilesAndDirs, Dir));
+  }
+
   void addEntry(StringRef Path, const vfs::Status &Status) {
     FilesAndDirs[Path] = Status;
   }
@@ -75,11 +119,11 @@
 
 TEST(VirtualFileSystemTest, StatusQueries) {
   IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
-  ErrorOr<vfs::Status> Status((error_code()));
+  ErrorOr<vfs::Status> Status((std::error_code()));
 
   D->addRegularFile("/foo");
   Status = D->status("/foo");
-  ASSERT_EQ(errc::success, Status.getError());
+  ASSERT_FALSE(Status.getError());
   EXPECT_TRUE(Status->isStatusKnown());
   EXPECT_FALSE(Status->isDirectory());
   EXPECT_TRUE(Status->isRegularFile());
@@ -89,7 +133,7 @@
 
   D->addDirectory("/bar");
   Status = D->status("/bar");
-  ASSERT_EQ(errc::success, Status.getError());
+  ASSERT_FALSE(Status.getError());
   EXPECT_TRUE(Status->isStatusKnown());
   EXPECT_TRUE(Status->isDirectory());
   EXPECT_FALSE(Status->isRegularFile());
@@ -99,7 +143,7 @@
 
   D->addSymlink("/baz");
   Status = D->status("/baz");
-  ASSERT_EQ(errc::success, Status.getError());
+  ASSERT_FALSE(Status.getError());
   EXPECT_TRUE(Status->isStatusKnown());
   EXPECT_FALSE(Status->isDirectory());
   EXPECT_FALSE(Status->isRegularFile());
@@ -109,13 +153,13 @@
 
   EXPECT_TRUE(Status->equivalent(*Status));
   ErrorOr<vfs::Status> Status2 = D->status("/foo");
-  ASSERT_EQ(errc::success, Status2.getError());
+  ASSERT_FALSE(Status2.getError());
   EXPECT_FALSE(Status->equivalent(*Status2));
 }
 
 TEST(VirtualFileSystemTest, BaseOnlyOverlay) {
   IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
-  ErrorOr<vfs::Status> Status((error_code()));
+  ErrorOr<vfs::Status> Status((std::error_code()));
   EXPECT_FALSE(Status = D->status("/foo"));
 
   IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D));
@@ -123,11 +167,11 @@
 
   D->addRegularFile("/foo");
   Status = D->status("/foo");
-  EXPECT_EQ(errc::success, Status.getError());
+  EXPECT_FALSE(Status.getError());
 
-  ErrorOr<vfs::Status> Status2((error_code()));
+  ErrorOr<vfs::Status> Status2((std::error_code()));
   Status2 = O->status("/foo");
-  EXPECT_EQ(errc::success, Status2.getError());
+  EXPECT_FALSE(Status2.getError());
   EXPECT_TRUE(Status->equivalent(*Status2));
 }
 
@@ -140,25 +184,26 @@
   O->pushOverlay(Middle);
   O->pushOverlay(Top);
 
-  ErrorOr<vfs::Status> Status1((error_code())), Status2((error_code())),
-      Status3((error_code())), StatusB((error_code())), StatusM((error_code())),
-      StatusT((error_code()));
+  ErrorOr<vfs::Status> Status1((std::error_code())),
+      Status2((std::error_code())), Status3((std::error_code())),
+      StatusB((std::error_code())), StatusM((std::error_code())),
+      StatusT((std::error_code()));
 
   Base->addRegularFile("/foo");
   StatusB = Base->status("/foo");
-  ASSERT_EQ(errc::success, StatusB.getError());
+  ASSERT_FALSE(StatusB.getError());
   Status1 = O->status("/foo");
-  ASSERT_EQ(errc::success, Status1.getError());
+  ASSERT_FALSE(Status1.getError());
   Middle->addRegularFile("/foo");
   StatusM = Middle->status("/foo");
-  ASSERT_EQ(errc::success, StatusM.getError());
+  ASSERT_FALSE(StatusM.getError());
   Status2 = O->status("/foo");
-  ASSERT_EQ(errc::success, Status2.getError());
+  ASSERT_FALSE(Status2.getError());
   Top->addRegularFile("/foo");
   StatusT = Top->status("/foo");
-  ASSERT_EQ(errc::success, StatusT.getError());
+  ASSERT_FALSE(StatusT.getError());
   Status3 = O->status("/foo");
-  ASSERT_EQ(errc::success, Status3.getError());
+  ASSERT_FALSE(Status3.getError());
 
   EXPECT_TRUE(Status1->equivalent(*StatusB));
   EXPECT_TRUE(Status2->equivalent(*StatusM));
@@ -181,15 +226,15 @@
 
   // non-merged paths should be the same
   ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only");
-  ASSERT_EQ(errc::success, Status1.getError());
+  ASSERT_FALSE(Status1.getError());
   ErrorOr<vfs::Status> Status2 = O->status("/lower-only");
-  ASSERT_EQ(errc::success, Status2.getError());
+  ASSERT_FALSE(Status2.getError());
   EXPECT_TRUE(Status1->equivalent(*Status2));
 
   Status1 = Upper->status("/upper-only");
-  ASSERT_EQ(errc::success, Status1.getError());
+  ASSERT_FALSE(Status1.getError());
   Status2 = O->status("/upper-only");
-  ASSERT_EQ(errc::success, Status2.getError());
+  ASSERT_FALSE(Status2.getError());
   EXPECT_TRUE(Status1->equivalent(*Status2));
 }
 
@@ -201,24 +246,281 @@
       new vfs::OverlayFileSystem(Lower));
   O->pushOverlay(Upper);
 
-  ErrorOr<vfs::Status> Status((error_code()));
+  ErrorOr<vfs::Status> Status((std::error_code()));
   Lower->addDirectory("/both", sys::fs::owner_read);
   Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read);
   Status = O->status("/both");
-  ASSERT_EQ(errc::success, Status.getError());
+  ASSERT_FALSE(Status.getError());
   EXPECT_EQ(0740, Status->getPermissions());
 
   // permissions (as usual) are not recursively applied
   Lower->addRegularFile("/both/foo", sys::fs::owner_read);
   Upper->addRegularFile("/both/bar", sys::fs::owner_write);
   Status = O->status("/both/foo");
-  ASSERT_EQ(errc::success, Status.getError());
+  ASSERT_FALSE( Status.getError());
   EXPECT_EQ(0400, Status->getPermissions());
   Status = O->status("/both/bar");
-  ASSERT_EQ(errc::success, Status.getError());
+  ASSERT_FALSE(Status.getError());
   EXPECT_EQ(0200, Status->getPermissions());
 }
 
+namespace {
+struct ScopedDir {
+  SmallString<128> Path;
+  ScopedDir(const Twine &Name, bool Unique=false) {
+    std::error_code EC;
+    if (Unique) {
+      EC =  llvm::sys::fs::createUniqueDirectory(Name, Path);
+    } else {
+      Path = Name.str();
+      EC = llvm::sys::fs::create_directory(Twine(Path));
+    }
+    if (EC)
+      Path = "";
+    EXPECT_FALSE(EC);
+  }
+  ~ScopedDir() {
+    if (Path != "")
+      EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+  }
+  operator StringRef() { return Path.str(); }
+};
+}
+
+TEST(VirtualFileSystemTest, BasicRealFSIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  std::error_code EC;
+  vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  EXPECT_EQ(vfs::directory_iterator(), I); // empty directory is empty
+
+  ScopedDir _a(TestDirectory+"/a");
+  ScopedDir _ab(TestDirectory+"/a/b");
+  ScopedDir _c(TestDirectory+"/c");
+  ScopedDir _cd(TestDirectory+"/c/d");
+
+  I = FS->dir_begin(Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::directory_iterator(), I);
+  // Check either a or c, since we can't rely on the iteration order.
+  EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c"));
+  I.increment(EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::directory_iterator(), I);
+  EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c"));
+  I.increment(EC);
+  EXPECT_EQ(vfs::directory_iterator(), I);
+}
+
+TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  std::error_code EC;
+  auto I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  EXPECT_EQ(vfs::recursive_directory_iterator(), I); // empty directory is empty
+
+  ScopedDir _a(TestDirectory+"/a");
+  ScopedDir _ab(TestDirectory+"/a/b");
+  ScopedDir _c(TestDirectory+"/c");
+  ScopedDir _cd(TestDirectory+"/c/d");
+
+  I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::recursive_directory_iterator(), I);
+
+
+  std::vector<std::string> Contents;
+  for (auto E = vfs::recursive_directory_iterator(); !EC && I != E;
+       I.increment(EC)) {
+    Contents.push_back(I->getName());
+  }
+
+  // Check contents, which may be in any order
+  EXPECT_EQ(4U, Contents.size());
+  int Counts[4] = { 0, 0, 0, 0 };
+  for (const std::string &Name : Contents) {
+    ASSERT_FALSE(Name.empty());
+    int Index = Name[Name.size()-1] - 'a';
+    ASSERT_TRUE(Index >= 0 && Index < 4);
+    Counts[Index]++;
+  }
+  EXPECT_EQ(1, Counts[0]); // a
+  EXPECT_EQ(1, Counts[1]); // b
+  EXPECT_EQ(1, Counts[2]); // c
+  EXPECT_EQ(1, Counts[3]); // d
+}
+
+template <typename T, size_t N>
+std::vector<StringRef> makeStringRefVector(const T (&Arr)[N]) {
+  std::vector<StringRef> Vec;
+  for (size_t i = 0; i != N; ++i)
+    Vec.push_back(Arr[i]);
+  return Vec;
+}
+
+template <typename DirIter>
+static void checkContents(DirIter I, ArrayRef<StringRef> Expected) {
+  std::error_code EC;
+  auto ExpectedIter = Expected.begin(), ExpectedEnd = Expected.end();
+  for (DirIter E;
+       !EC && I != E && ExpectedIter != ExpectedEnd;
+       I.increment(EC), ++ExpectedIter)
+    EXPECT_EQ(*ExpectedIter, I->getName());
+
+  EXPECT_EQ(ExpectedEnd, ExpectedIter);
+  EXPECT_EQ(DirIter(), I);
+}
+
+TEST(VirtualFileSystemTest, OverlayIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
+
+  Lower->addRegularFile("/file1");
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file1"));
+
+  Upper->addRegularFile("/file2");
+  {
+    const char *Contents[] = {"/file2", "/file1"};
+    checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents));
+  }
+
+  Lower->addDirectory("/dir1");
+  Lower->addRegularFile("/dir1/foo");
+  Upper->addDirectory("/dir2");
+  Upper->addRegularFile("/dir2/foo");
+  checkContents(O->dir_begin("/dir2", EC), ArrayRef<StringRef>("/dir2/foo"));
+  {
+    const char *Contents[] = {"/dir2", "/file2", "/dir1", "/file1"};
+    checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents));
+  }
+}
+
+TEST(VirtualFileSystemTest, OverlayRecursiveIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                ArrayRef<StringRef>());
+
+  Lower->addRegularFile("/file1");
+  checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                ArrayRef<StringRef>("/file1"));
+
+  Upper->addDirectory("/dir");
+  Upper->addRegularFile("/dir/file2");
+  {
+    const char *Contents[] = {"/dir", "/dir/file2", "/file1"};
+    checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                  makeStringRefVector(Contents));
+  }
+
+  Lower->addDirectory("/dir1");
+  Lower->addRegularFile("/dir1/foo");
+  Lower->addDirectory("/dir1/a");
+  Lower->addRegularFile("/dir1/a/b");
+  Middle->addDirectory("/a");
+  Middle->addDirectory("/a/b");
+  Middle->addDirectory("/a/b/c");
+  Middle->addRegularFile("/a/b/c/d");
+  Middle->addRegularFile("/hiddenByUp");
+  Upper->addDirectory("/dir2");
+  Upper->addRegularFile("/dir2/foo");
+  Upper->addRegularFile("/hiddenByUp");
+  checkContents(vfs::recursive_directory_iterator(*O, "/dir2", EC),
+                ArrayRef<StringRef>("/dir2/foo"));
+  {
+    const char *Contents[] = { "/dir", "/dir/file2", "/dir2", "/dir2/foo",
+        "/hiddenByUp", "/a", "/a/b", "/a/b/c", "/a/b/c/d", "/dir1", "/dir1/a",
+        "/dir1/a/b", "/dir1/foo", "/file1" };
+    checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                  makeStringRefVector(Contents));
+  }
+}
+
+TEST(VirtualFileSystemTest, ThreeLevelIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
+
+  Middle->addRegularFile("/file2");
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file2"));
+
+  Lower->addRegularFile("/file1");
+  Upper->addRegularFile("/file3");
+  {
+    const char *Contents[] = {"/file3", "/file2", "/file1"};
+    checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents));
+  }
+}
+
+TEST(VirtualFileSystemTest, HiddenInIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  Lower->addRegularFile("/onlyInLow", sys::fs::owner_read);
+  Lower->addRegularFile("/hiddenByMid", sys::fs::owner_read);
+  Lower->addRegularFile("/hiddenByUp", sys::fs::owner_read);
+  Middle->addRegularFile("/onlyInMid", sys::fs::owner_write);
+  Middle->addRegularFile("/hiddenByMid", sys::fs::owner_write);
+  Middle->addRegularFile("/hiddenByUp", sys::fs::owner_write);
+  Upper->addRegularFile("/onlyInUp", sys::fs::owner_all);
+  Upper->addRegularFile("/hiddenByUp", sys::fs::owner_all);
+  {
+    const char *Contents[] = {"/hiddenByUp", "/onlyInUp", "/hiddenByMid",
+                              "/onlyInMid", "/onlyInLow"};
+    checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents));
+  }
+
+  // Make sure we get the top-most entry
+  {
+    std::error_code EC;
+    vfs::directory_iterator I = O->dir_begin("/", EC), E;
+    for ( ; !EC && I != E; I.increment(EC))
+      if (I->getName() == "/hiddenByUp")
+        break;
+    ASSERT_NE(E, I);
+    EXPECT_EQ(sys::fs::owner_all, I->getPermissions());
+  }
+  {
+    std::error_code EC;
+    vfs::directory_iterator I = O->dir_begin("/", EC), E;
+    for ( ; !EC && I != E; I.increment(EC))
+      if (I->getName() == "/hiddenByMid")
+        break;
+    ASSERT_NE(E, I);
+    EXPECT_EQ(sys::fs::owner_write, I->getPermissions());
+  }
+}
+
 // NOTE: in the tests below, we use '//root/' as our root directory, since it is
 // a legal *absolute* path on Windows as well as *nix.
 class VFSFromYAMLTest : public ::testing::Test {
@@ -253,11 +555,11 @@
 TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) {
   IntrusiveRefCntPtr<vfs::FileSystem> FS;
   FS = getFromYAMLString("");
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString("[]");
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString("'string'");
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   EXPECT_EQ(3, NumDiagnostics);
 }
 
@@ -284,7 +586,7 @@
                         "]\n"
                         "}",
                         Lower);
-  ASSERT_TRUE(FS.getPtr() != NULL);
+  ASSERT_TRUE(FS.get() != nullptr);
 
   IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
       new vfs::OverlayFileSystem(Lower));
@@ -292,7 +594,7 @@
 
   // file
   ErrorOr<vfs::Status> S = O->status("//root/file1");
-  ASSERT_EQ(errc::success, S.getError());
+  ASSERT_FALSE(S.getError());
   EXPECT_EQ("//root/foo/bar/a", S->getName());
 
   ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
@@ -301,12 +603,13 @@
 
   // directory
   S = O->status("//root/");
-  ASSERT_EQ(errc::success, S.getError());
+  ASSERT_FALSE(S.getError());
   EXPECT_TRUE(S->isDirectory());
   EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID
 
   // broken mapping
-  EXPECT_EQ(errc::no_such_file_or_directory, O->status("//root/file2").getError());
+  EXPECT_EQ(O->status("//root/file2").getError(),
+            llvm::errc::no_such_file_or_directory);
   EXPECT_EQ(0, NumDiagnostics);
 }
 
@@ -327,17 +630,17 @@
                         "              ]\n"
                         "}]}",
                         Lower);
-  ASSERT_TRUE(FS.getPtr() != NULL);
+  ASSERT_TRUE(FS.get() != nullptr);
 
   IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
       new vfs::OverlayFileSystem(Lower));
   O->pushOverlay(FS);
 
   ErrorOr<vfs::Status> S = O->status("//root/XX");
-  ASSERT_EQ(errc::success, S.getError());
+  ASSERT_FALSE(S.getError());
 
   ErrorOr<vfs::Status> SS = O->status("//root/xx");
-  ASSERT_EQ(errc::success, SS.getError());
+  ASSERT_FALSE(SS.getError());
   EXPECT_TRUE(S->equivalent(*SS));
   SS = O->status("//root/xX");
   EXPECT_TRUE(S->equivalent(*SS));
@@ -363,18 +666,18 @@
                         "              ]\n"
                         "}]}",
                         Lower);
-  ASSERT_TRUE(FS.getPtr() != NULL);
+  ASSERT_TRUE(FS.get() != nullptr);
 
   IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
       new vfs::OverlayFileSystem(Lower));
   O->pushOverlay(FS);
 
   ErrorOr<vfs::Status> SS = O->status("//root/xx");
-  EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
   SS = O->status("//root/xX");
-  EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
   SS = O->status("//root/Xx");
-  EXPECT_EQ(errc::no_such_file_or_directory, SS.getError());
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
   EXPECT_EQ(0, NumDiagnostics);
 }
 
@@ -383,89 +686,89 @@
 
   // invalid YAML at top-level
   IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   // invalid YAML in roots
   FS = getFromYAMLString("{ 'roots':[}", Lower);
   // invalid YAML in directory
   FS = getFromYAMLString(
       "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}",
       Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
 
   // invalid configuration
   FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
 
   // invalid roots
   FS = getFromYAMLString("{ 'roots':'' }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString("{ 'roots':{} }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
 
   // invalid entries
   FS = getFromYAMLString(
       "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], "
                          "'external-contents': 'other' }",
                          Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString(
       "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
       Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString(
       "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
       Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString(
       "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }",
       Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString(
       "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }",
       Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString(
       "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }",
       Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
 
   // missing mandatory fields
   FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString(
       "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
 
   // duplicate keys
   FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLString(
       "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
       Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS =
       getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', "
                         "'external-contents':'blah' } ] }",
                         Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
 
   // missing version
   FS = getFromYAMLRawString("{ 'roots':[] }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
 
   // bad version number
   FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower);
-  EXPECT_EQ(NULL, FS.getPtr());
+  EXPECT_EQ(nullptr, FS.get());
   EXPECT_EQ(24, NumDiagnostics);
 }
 
@@ -487,7 +790,7 @@
       "    'external-contents': '//root/external/file'\n"
       "  }\n"
       "] }", Lower);
-  ASSERT_TRUE(NULL != FS.getPtr());
+  ASSERT_TRUE(nullptr != FS.get());
 
   // default true
   EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName());
@@ -511,7 +814,7 @@
       "    'external-contents': '//root/external/file'\n"
       "  }\n"
       "] }", Lower);
-  ASSERT_TRUE(NULL != FS.getPtr());
+  ASSERT_TRUE(nullptr != FS.get());
 
   // default
   EXPECT_EQ("//root/A", FS->status("//root/A")->getName());
@@ -530,11 +833,11 @@
       "  { 'type': 'file', 'name': '//root/path/to/file',\n"
       "    'external-contents': '//root/other' }]\n"
       "}", Lower);
-  ASSERT_TRUE(NULL != FS.getPtr());
-  EXPECT_EQ(errc::success, FS->status("//root/path/to/file").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/path/to").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/path").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/").getError());
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
 
   // at the start
   FS = getFromYAMLString(
@@ -543,11 +846,11 @@
       "    'contents': [ { 'type': 'file', 'name': 'file',\n"
       "                    'external-contents': '//root/other' }]}]\n"
       "}", Lower);
-  ASSERT_TRUE(NULL != FS.getPtr());
-  EXPECT_EQ(errc::success, FS->status("//root/path/to/file").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/path/to").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/path").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/").getError());
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
 
   // at the end
   FS = getFromYAMLString(
@@ -556,11 +859,11 @@
       "    'contents': [ { 'type': 'file', 'name': 'path/to/file',\n"
       "                    'external-contents': '//root/other' }]}]\n"
       "}", Lower);
-  ASSERT_TRUE(NULL != FS.getPtr());
-  EXPECT_EQ(errc::success, FS->status("//root/path/to/file").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/path/to").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/path").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/").getError());
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
 }
 
 TEST_F(VFSFromYAMLTest, TrailingSlashes) {
@@ -574,9 +877,58 @@
       "    'contents': [ { 'type': 'file', 'name': 'file',\n"
       "                    'external-contents': '//root/other' }]}]\n"
       "}", Lower);
-  ASSERT_TRUE(NULL != FS.getPtr());
-  EXPECT_EQ(errc::success, FS->status("//root/path/to/file").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/path/to").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/path").getError());
-  EXPECT_EQ(errc::success, FS->status("//root/").getError());
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+}
+
+TEST_F(VFSFromYAMLTest, DirectoryIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/");
+  Lower->addDirectory("//root/foo");
+  Lower->addDirectory("//root/foo/bar");
+  Lower->addRegularFile("//root/foo/bar/a");
+  Lower->addRegularFile("//root/foo/bar/b");
+  Lower->addRegularFile("//root/file3");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS =
+  getFromYAMLString("{ 'use-external-names': false,\n"
+                    "  'roots': [\n"
+                    "{\n"
+                    "  'type': 'directory',\n"
+                    "  'name': '//root/',\n"
+                    "  'contents': [ {\n"
+                    "                  'type': 'file',\n"
+                    "                  'name': 'file1',\n"
+                    "                  'external-contents': '//root/foo/bar/a'\n"
+                    "                },\n"
+                    "                {\n"
+                    "                  'type': 'file',\n"
+                    "                  'name': 'file2',\n"
+                    "                  'external-contents': '//root/foo/bar/b'\n"
+                    "                }\n"
+                    "              ]\n"
+                    "}\n"
+                    "]\n"
+                    "}",
+                    Lower);
+  ASSERT_TRUE(FS.get() != NULL);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  std::error_code EC;
+  {
+    const char *Contents[] = {"//root/file1", "//root/file2", "//root/file3",
+                              "//root/foo"};
+    checkContents(O->dir_begin("//root/", EC), makeStringRefVector(Contents));
+  }
+
+  {
+    const char *Contents[] = {"//root/foo/bar/a", "//root/foo/bar/b"};
+    checkContents(O->dir_begin("//root/foo/bar", EC),
+                  makeStringRefVector(Contents));
+  }
 }
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 94d4bbb..1695969 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -683,6 +683,13 @@
                "case (b):\n"
                "  return;\n"
                "}");
+
+  verifyFormat("switch (a) {\n"
+               "case some_namespace::\n"
+               "    some_constant:\n"
+               "  return;\n"
+               "}",
+               getLLVMStyleWithColumns(34));
 }
 
 TEST_F(FormatTest, CaseRanges) {
@@ -1257,13 +1264,13 @@
                    getLLVMStyleWithColumns(50)));
   // FIXME: One day we might want to implement adjustment of leading whitespace
   // of the consecutive lines in this kind of comment:
-  EXPECT_EQ("int\n"
-            "a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-            "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-            "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
-            format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-                   "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-                   "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+  EXPECT_EQ("double\n"
+            "    a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+            "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+            "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+            format("double a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+                   "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+                   "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                    getLLVMStyleWithColumns(49)));
 }
 
@@ -1877,6 +1884,26 @@
 
   verifyFormat("enum ShortEnum { A, B, C };");
   verifyGoogleFormat("enum ShortEnum { A, B, C };");
+
+  EXPECT_EQ("enum KeepEmptyLines {\n"
+            "  ONE,\n"
+            "\n"
+            "  TWO,\n"
+            "\n"
+            "  THREE\n"
+            "}",
+            format("enum KeepEmptyLines {\n"
+                   "  ONE,\n"
+                   "\n"
+                   "  TWO,\n"
+                   "\n"
+                   "\n"
+                   "  THREE\n"
+                   "}"));
+  verifyFormat("enum E { // comment\n"
+               "  ONE,\n"
+               "  TWO\n"
+               "};");
 }
 
 TEST_F(FormatTest, FormatsEnumsWithErrors) {
@@ -2142,11 +2169,14 @@
   // Here, everything other than the "}" would fit on a line.
   verifyFormat("static int LooooooooooooooooooooooooongVariable[1] = {\n"
                "    10000000000000000000000000};");
-  EXPECT_EQ("S s = {a, b};", format("S s = {\n"
-                                    "  a,\n"
-                                    "\n"
-                                    "  b\n"
-                                    "};"));
+  EXPECT_EQ("S s = {a,\n"
+            "\n"
+            "       b};",
+            format("S s = {\n"
+                   "  a,\n"
+                   "\n"
+                   "  b\n"
+                   "};"));
 
   // FIXME: This would fit into the column limit if we'd fit "{ {" on the first
   // line. However, the formatting looks a bit off and this probably doesn't
@@ -2450,7 +2480,6 @@
             "};",
             format("class A  :  public QObject {\n"
                    "     Q_Object\n"
-                   "\n"
                    "  A() {\n}\n"
                    "}  ;"));
 }
@@ -2658,7 +2687,7 @@
   EXPECT_EQ("int\n"
             "#define A\n"
             "    a;",
-            format("int\n#define A\na;", getGoogleStyle()));
+            format("int\n#define A\na;"));
   verifyFormat("functionCallTo(\n"
                "    someOtherFunction(\n"
                "        withSomeParameters, whichInSequence,\n"
@@ -3330,7 +3359,7 @@
   // 2) break after return type.
   verifyFormat(
       "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    bbbbbbbbbbbbbb(Cccccccccccccc cccccccccccccccccccccccccc);",
+      "bbbbbbbbbbbbbb(Cccccccccccccc cccccccccccccccccccccccccc);",
       getGoogleStyle());
 
   // 3) break after (.
@@ -3342,8 +3371,8 @@
   // 4) break before after nested name specifiers.
   verifyFormat(
       "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    SomeClasssssssssssssssssssssssssssssssssssssss::\n"
-      "        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(Cccccccccccccc cccccccccc);",
+      "SomeClasssssssssssssssssssssssssssssssssssssss::\n"
+      "    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(Cccccccccccccc cccccccccc);",
       getGoogleStyle());
 
   // However, there are exceptions, if a sufficient amount of lines can be
@@ -3357,9 +3386,9 @@
                "                                  Cccccccccccccc cccccccccc);");
   verifyFormat(
       "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    bbbbbbbbbbb(Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n"
-      "                Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n"
-      "                Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc);",
+      "bbbbbbbbbbb(Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n"
+      "            Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n"
+      "            Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc);",
       getGoogleStyle());
   verifyFormat(
       "Aaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(Cccccccccccccc cccccccccc,\n"
@@ -3462,6 +3491,13 @@
                "    int parameter) const override {}",
                Style);
 
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) const\n"
+               "{\n"
+               "}",
+               Style);
+
   // Unless these are unknown annotations.
   verifyFormat("void SomeFunction(aaaaaaaaaa aaaaaaaaaaaaaaa,\n"
                "                  aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
@@ -4135,6 +4171,12 @@
                "     L\"cccc\");",
                Break);
 
+  // As we break before unary operators, breaking right after them is bad.
+  verifyFormat("string foo = abc ? \"x\"\n"
+               "                   \"blah blah blah blah blah blah\"\n"
+               "                 : \"y\";",
+               Break);
+
   // Don't break if there is no column gain.
   verifyFormat("f(\"aaaa\"\n"
                "  \"bbbb\");",
@@ -4544,8 +4586,11 @@
                "  (a->*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)(\n"
                "      aaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb);\n"
                "}");
+  verifyFormat(
+      "(aaaaaaaaaa->*bbbbbbb)(\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa));");
   FormatStyle Style = getLLVMStyle();
-  Style.PointerBindsToType = true;
+  Style.PointerAlignment = FormatStyle::PAS_Left;
   verifyFormat("typedef bool* (Class::*Member)() const;", Style);
 }
 
@@ -4640,6 +4685,11 @@
   verifyFormat("Deleted &operator=(const Deleted &)&& = delete;");
   verifyGoogleFormat("Deleted& operator=(const Deleted&)& = default;");
   verifyGoogleFormat("Deleted& operator=(const Deleted&)&& = delete;");
+
+  verifyFormat("string // break\n"
+               "operator()() & {}");
+  verifyFormat("string // break\n"
+               "operator()() && {}");
 }
 
 TEST_F(FormatTest, UnderstandsNewAndDelete) {
@@ -4698,8 +4748,10 @@
   verifyFormat("auto a = [](int **&, int ***) {};");
   verifyFormat("auto PointerBinding = [](const char *S) {};");
   verifyFormat("typedef typeof(int(int, int)) *MyFunc;");
+  verifyFormat("[](const decltype(*a) &value) {}");
   verifyIndependentOfContext("typedef void (*f)(int *a);");
   verifyIndependentOfContext("int i{a * b};");
+  verifyIndependentOfContext("aaa && aaa->f();");
 
   verifyIndependentOfContext("InvalidRegions[*R] = 0;");
 
@@ -4779,13 +4831,13 @@
   verifyGoogleFormat("T** t = new T*();");
 
   FormatStyle PointerLeft = getLLVMStyle();
-  PointerLeft.PointerBindsToType = true;
+  PointerLeft.PointerAlignment = FormatStyle::PAS_Left;
   verifyFormat("delete *x;", PointerLeft);
   verifyFormat("STATIC_ASSERT((a & b) == 0);");
   verifyFormat("STATIC_ASSERT(0 == (a & b));");
   verifyFormat("template <bool a, bool b> "
-               "typename t::if<x && y>::type f() {};");
-  verifyFormat("template <int *y> f() {};");
+               "typename t::if<x && y>::type f() {}");
+  verifyFormat("template <int *y> f() {}");
   verifyFormat("vector<int *> v;");
   verifyFormat("vector<int *const> v;");
   verifyFormat("vector<int *const **const *> v;");
@@ -4797,9 +4849,12 @@
   verifyIndependentOfContext("MACRO(int *i);");
   verifyIndependentOfContext("MACRO(auto *a);");
   verifyIndependentOfContext("MACRO(const A *a);");
+  verifyIndependentOfContext("MACRO('0' <= c && c <= '9');");
   // FIXME: Is there a way to make this work?
   // verifyIndependentOfContext("MACRO(A *a);");
 
+  verifyFormat("DatumHandle const *operator->() const { return input_; }");
+
   EXPECT_EQ("#define OP(x)                                    \\\n"
             "  ostream &operator<<(ostream &s, const A &a) {  \\\n"
             "    return s << a.DebugString();                 \\\n"
@@ -4813,6 +4868,22 @@
   // FIXME: We cannot handle this case yet; we might be able to figure out that
   // foo<x> d > v; doesn't make sense.
   verifyFormat("foo<a < b && c> d > v;");
+
+  FormatStyle PointerMiddle = getLLVMStyle();
+  PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle;
+  verifyFormat("delete *x;", PointerMiddle);
+  verifyFormat("int * x;", PointerMiddle);
+  verifyFormat("template <int * y> f() {}", PointerMiddle);
+  verifyFormat("int * f(int * a) {}", PointerMiddle);
+  verifyFormat("int main(int argc, char ** argv) {}", PointerMiddle);
+  verifyFormat("Test::Test(int b) : a(b * b) {}", PointerMiddle);
+  verifyFormat("A<int *> a;", PointerMiddle);
+  verifyFormat("A<int **> a;", PointerMiddle);
+  verifyFormat("A<int *, int *> a;", PointerMiddle);
+  verifyFormat("A<int * []> a;", PointerMiddle);
+  verifyFormat("A = new SomeType * [Length]();", PointerMiddle);
+  verifyFormat("A = new SomeType * [Length];", PointerMiddle);
+  verifyFormat("T ** t = new T *;", PointerMiddle);
 }
 
 TEST_F(FormatTest, UnderstandsAttributes) {
@@ -4827,7 +4898,7 @@
   verifyFormat("template <class... Ts> void Foo(Ts *... ts) {}");
 
   FormatStyle PointersLeft = getLLVMStyle();
-  PointersLeft.PointerBindsToType = true;
+  PointersLeft.PointerAlignment = FormatStyle::PAS_Left;
   verifyFormat("template <class... Ts> void Foo(Ts*... ts) {}", PointersLeft);
 }
 
@@ -4986,28 +5057,51 @@
   verifyFormat("void f() { function(*some_pointer_var)[0] = 10; }");
 }
 
+TEST_F(FormatTest, BreaksLongVariableDeclarations) {
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable;");
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType const\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable;");
+
+  // Different ways of ()-initializiation.
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable(1);");
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable(a);");
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable({});");
+}
+
 TEST_F(FormatTest, BreaksLongDeclarations) {
   verifyFormat("typedef LoooooooooooooooooooooooooooooooooooooooongType\n"
-               "    AnotherNameForTheLongType;",
-               getGoogleStyle());
+               "    AnotherNameForTheLongType;");
   verifyFormat("typedef LongTemplateType<aaaaaaaaaaaaaaaaaaa()>\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
-               getGoogleStyle());
-  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
-               "    LoooooooooooooooooooooooooooooooooooooooongVariable;",
-               getGoogleStyle());
-  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType const\n"
-               "    LoooooooooooooooooooooooooooooooooooooooongVariable;",
-               getGoogleStyle());
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
-               "    LoooooooooooooooooooooooooooooooongFunctionDeclaration();",
-               getGoogleStyle());
+               "LoooooooooooooooooooooooooooooooongFunctionDeclaration();");
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
                "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType const\n"
                "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
   verifyFormat("decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n"
                "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
+  FormatStyle Indented = getLLVMStyle();
+  Indented.IndentWrappedFunctionNames = true;
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
+               "    LoooooooooooooooooooooooooooooooongFunctionDeclaration();",
+               Indented);
+  verifyFormat(
+      "LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
+      "    LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}",
+      Indented);
+  verifyFormat(
+      "LoooooooooooooooooooooooooooooooooooooooongReturnType const\n"
+      "    LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}",
+      Indented);
+  verifyFormat(
+      "decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n"
+      "    LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}",
+      Indented);
 
   // FIXME: Without the comment, this breaks after "(".
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType  // break\n"
@@ -5067,6 +5161,10 @@
 
   verifyGoogleFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<int>\n"
                      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaa];");
+  verifyFormat(
+      "aaaaaaaaaaa aaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaa->aaaaaaaaa[0]\n"
+      "                                  .aaaaaaa[0]\n"
+      "                                  .aaaaaaaaaaaaaaaaaaaaaa();");
 }
 
 TEST_F(FormatTest, LineStartsWithSpecialCharacter) {
@@ -5242,7 +5340,7 @@
 }
 
 TEST_F(FormatTest, LayoutBraceInitializersInReturnStatement) {
-  verifyFormat("return (a)(b) {1, 2, 3};");
+  verifyFormat("return (a)(b){1, 2, 3};");
 }
 
 TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
@@ -5272,6 +5370,7 @@
 
   verifyFormat("int foo(int i) { return fo1{}(i); }");
   verifyFormat("int foo(int i) { return fo1{}(i); }");
+  verifyFormat("auto i = decltype(x){};");
 
   // In combination with BinPackParameters = false.
   FormatStyle NoBinPacking = getLLVMStyle();
@@ -5370,7 +5469,8 @@
       "             BracedList{ // comment 1 (Forcing interesting break)\n"
       "                         param1, param2,\n"
       "                         // comment 2\n"
-      "                         param3, param4 });",
+      "                         param3, param4\n"
+      "             });",
       ExtraSpaces);
   verifyFormat(
       "std::this_thread::sleep_for(\n"
@@ -6491,6 +6591,12 @@
       "  @\"dte\" : [NSDate date],\n"
       "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
       "};");
+  verifyFormat("NSMutableDictionary *dictionary =\n"
+               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
+               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
+               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
+               "      cccccccccccccccc : ccccccccccccccc\n"
+               "    }];");
 }
 
 TEST_F(FormatTest, ObjCArrayLiterals) {
@@ -7052,7 +7158,7 @@
   verifyFormat("void f() {\n"
                "  return g() {}\n"
                "  void h() {}");
-  verifyFormat("int a[] = {void forgot_closing_brace() {f();\n"
+  verifyFormat("int a[] = {void forgot_closing_brace(){f();\n"
                "g();\n"
                "}");
 }
@@ -7659,6 +7765,11 @@
                "  Y = 0,\n"
                "}\n",
                BreakBeforeBrace);
+  verifyFormat("enum X\n"
+               "{\n"
+               "  Y = 0\n"
+               "}\n",
+               BreakBeforeBrace);
 
   verifyFormat("@interface BSApplicationController ()\n"
                "{\n"
@@ -8010,14 +8121,13 @@
   CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
   CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma);
   CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine);
-  CHECK_PARSE_BOOL(DerivePointerBinding);
+  CHECK_PARSE_BOOL(DerivePointerAlignment);
   CHECK_PARSE_BOOL(IndentCaseLabels);
+  CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
-  CHECK_PARSE_BOOL(PointerBindsToType);
   CHECK_PARSE_BOOL(Cpp11BracedListStyle);
-  CHECK_PARSE_BOOL(IndentFunctionDeclarationAfterType);
   CHECK_PARSE_BOOL(SpacesInParentheses);
   CHECK_PARSE_BOOL(SpacesInAngles);
   CHECK_PARSE_BOOL(SpaceInEmptyParentheses);
@@ -8040,6 +8150,11 @@
   CHECK_PARSE("IndentWidth: 32", IndentWidth, 32u);
   CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u);
 
+  Style.PointerAlignment = FormatStyle::PAS_Middle;
+  CHECK_PARSE("PointerAlignment: Left", PointerAlignment, FormatStyle::PAS_Left);
+  CHECK_PARSE("PointerAlignment: Right", PointerAlignment, FormatStyle::PAS_Right);
+  CHECK_PARSE("PointerAlignment: Middle", PointerAlignment, FormatStyle::PAS_Middle);
+
   Style.Standard = FormatStyle::LS_Auto;
   CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03);
   CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Cpp11);
@@ -8120,10 +8235,10 @@
   CHECK_PARSE("Language: Cpp\n"
               "IndentWidth: 12",
               IndentWidth, 12u);
-  EXPECT_EQ(llvm::errc::not_supported,
-            parseConfiguration("Language: JavaScript\n"
+  EXPECT_EQ(parseConfiguration("Language: JavaScript\n"
                                "IndentWidth: 34",
-                               &Style));
+                               &Style),
+            ParseError::Unsuitable);
   EXPECT_EQ(12u, Style.IndentWidth);
   CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
   EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
@@ -8133,9 +8248,10 @@
               "IndentWidth: 12",
               IndentWidth, 12u);
   CHECK_PARSE("IndentWidth: 23", IndentWidth, 23u);
-  EXPECT_EQ(llvm::errc::not_supported, parseConfiguration("Language: Cpp\n"
-                                                          "IndentWidth: 34",
-                                                          &Style));
+  EXPECT_EQ(parseConfiguration("Language: Cpp\n"
+                               "IndentWidth: 34",
+                               &Style),
+            ParseError::Unsuitable);
   EXPECT_EQ(23u, Style.IndentWidth);
   CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
   EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
@@ -8174,43 +8290,41 @@
   Style.IndentWidth = 234;
   Style.BreakBeforeBraces = FormatStyle::BS_Linux;
   Style.TabWidth = 345;
-  EXPECT_EQ(llvm::errc::success,
-            parseConfiguration("---\n"
-                               "IndentWidth: 456\n"
-                               "BreakBeforeBraces: Allman\n"
-                               "---\n"
-                               "Language: JavaScript\n"
-                               "IndentWidth: 111\n"
-                               "TabWidth: 111\n"
-                               "---\n"
-                               "Language: Cpp\n"
-                               "BreakBeforeBraces: Stroustrup\n"
-                               "TabWidth: 789\n"
-                               "...\n",
-                               &Style));
+  EXPECT_FALSE(parseConfiguration("---\n"
+                                  "IndentWidth: 456\n"
+                                  "BreakBeforeBraces: Allman\n"
+                                  "---\n"
+                                  "Language: JavaScript\n"
+                                  "IndentWidth: 111\n"
+                                  "TabWidth: 111\n"
+                                  "---\n"
+                                  "Language: Cpp\n"
+                                  "BreakBeforeBraces: Stroustrup\n"
+                                  "TabWidth: 789\n"
+                                  "...\n",
+                                  &Style));
   EXPECT_EQ(123u, Style.ColumnLimit);
   EXPECT_EQ(456u, Style.IndentWidth);
   EXPECT_EQ(FormatStyle::BS_Stroustrup, Style.BreakBeforeBraces);
   EXPECT_EQ(789u, Style.TabWidth);
 
-
-  EXPECT_EQ(llvm::errc::invalid_argument,
-            parseConfiguration("---\n"
+  EXPECT_EQ(parseConfiguration("---\n"
                                "Language: JavaScript\n"
                                "IndentWidth: 56\n"
                                "---\n"
                                "IndentWidth: 78\n"
                                "...\n",
-                               &Style));
-  EXPECT_EQ(llvm::errc::invalid_argument,
-            parseConfiguration("---\n"
+                               &Style),
+            ParseError::Error);
+  EXPECT_EQ(parseConfiguration("---\n"
                                "Language: JavaScript\n"
                                "IndentWidth: 56\n"
                                "---\n"
                                "Language: JavaScript\n"
                                "IndentWidth: 78\n"
                                "...\n",
-                               &Style));
+                               &Style),
+            ParseError::Error);
 
   EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
 }
@@ -8590,10 +8704,12 @@
             format("NSArray*a=[[NSArray alloc]initWithArray:@[ @\"a\" ]\n"
                    "             copyItems:YES];",
                    Style));
+  // FIXME: This does not seem right, there should be more indentation before
+  // the array literal's entries. Nested blocks have the same problem.
   EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[\n"
-            "                                               @\"a\",\n"
-            "                                               @\"a\"\n"
-            "                                            ]\n"
+            "    @\"a\",\n"
+            "    @\"a\"\n"
+            "]\n"
             "                                  copyItems:YES];",
             format("NSArray* a = [[NSArray alloc] initWithArray:@[\n"
                    "     @\"a\",\n"
@@ -8637,6 +8753,8 @@
   verifyFormat("void f() {\n"
                "  SomeFunction([](decltype(x), A *a) {});\n"
                "}");
+  verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "    [](const aaaaaaaaaa &a) { return a; });");
 
   // Lambdas with return types.
   verifyFormat("int c = []() -> int { return 2; }();\n");
@@ -8644,7 +8762,7 @@
   verifyFormat("Foo([]() -> std::vector<int> { return {2}; }());");
   verifyFormat("auto aaaaaaaa = [](int i, // break for some reason\n"
                "                   int j) -> int {\n"
-               "  return fffffffffffffffffffffffffffffffffffffff(i * j);\n"
+               "  return ffffffffffffffffffffffffffffffffffffffffffff(i * j);\n"
                "};");
 
   // Multiple lambdas in the same parentheses change indentation rules.
@@ -8657,6 +8775,9 @@
                "               return j;\n"
                "             });");
 
+  // More complex introducers.
+  verifyFormat("return [i, args...] {};");
+
   // Not lambdas.
   verifyFormat("constexpr char hello[]{\"hello\"};");
   verifyFormat("double &operator[](int i) { return 0; }\n"
@@ -8949,7 +9070,7 @@
             "=======\n"
             "Other \\\n"
             ">>>>>>>\n"
-            "End int i;\n",
+            "    End int i;\n",
             format("#define Macro \\\n"
                    "<<<<<<<\n"
                    "  Something \\\n"
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index ecf4e69..f8802b8 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -88,6 +88,31 @@
   verifyFormat("var {a, b} = {a: 1, b: 2};");
 }
 
+TEST_F(FormatTestJS, ContainerLiterals) {
+  verifyFormat("return {\n"
+               "  link: function() {\n"
+               "    f();  //\n"
+               "  }\n"
+               "};");
+  verifyFormat("return {\n"
+               "  a: a,\n"
+               "  link: function() {\n"
+               "    f();  //\n"
+               "  }\n"
+               "};");
+  verifyFormat("return {\n"
+               "  a: a,\n"
+               "  link:\n"
+               "      function() {\n"
+               "        f();  //\n"
+               "      },\n"
+               "  link:\n"
+               "      function() {\n"
+               "        f();  //\n"
+               "      }\n"
+               "};");
+}
+
 TEST_F(FormatTestJS, SpacesInContainerLiterals) {
   verifyFormat("var arr = [1, 2, 3];");
   verifyFormat("var obj = {a: 1, b: 2, c: 3};");
@@ -113,7 +138,18 @@
                "});  // goog.scope");
 }
 
-TEST_F(FormatTestJS, Closures) {
+TEST_F(FormatTestJS, FormatsFreestandingFunctions) {
+  verifyFormat("function outer1(a, b) {\n"
+               "  function inner1(a, b) { return a; }\n"
+               "  inner1(a, b);\n"
+               "}\n"
+               "function outer2(a, b) {\n"
+               "  function inner2(a, b) { return a; }\n"
+               "  inner2(a, b);\n"
+               "}");
+}
+
+TEST_F(FormatTestJS, FunctionLiterals) {
   verifyFormat("doFoo(function() { return 1; });");
   verifyFormat("var func = function() { return 1; };");
   verifyFormat("return {\n"
@@ -137,6 +173,14 @@
                "  foo();\n"
                "  bar();\n"
                "}, this);");
+  verifyFormat("return {\n"
+               "  a: 'E',\n"
+               "  b: function() {\n"
+               "    return function() {\n"
+               "      f();  //\n"
+               "    };\n"
+               "  }\n"
+               "};");
 
   verifyFormat("var x = {a: function() { return 1; }};",
                getGoogleJSStyleWithColumns(38));
@@ -144,6 +188,46 @@
                "  a: function() { return 1; }\n"
                "};",
                getGoogleJSStyleWithColumns(37));
+
+  verifyFormat("return {\n"
+               "  a: function SomeFunction() {\n"
+               "    // ...\n"
+               "    return 1;\n"
+               "  }\n"
+               "};");
+}
+
+TEST_F(FormatTestJS, MultipleFunctionLiterals) {
+  verifyFormat("promise.then(\n"
+               "    function success() {\n"
+               "      doFoo();\n"
+               "      doBar();\n"
+               "    },\n"
+               "    function error() {\n"
+               "      doFoo();\n"
+               "      doBaz();\n"
+               "    },\n"
+               "    []);\n");
+  verifyFormat("promise.then(\n"
+               "    function success() {\n"
+               "      doFoo();\n"
+               "      doBar();\n"
+               "    },\n"
+               "    [],\n"
+               "    function error() {\n"
+               "      doFoo();\n"
+               "      doBaz();\n"
+               "    });\n");
+  // FIXME: Here, we should probably break right after the "(" for consistency.
+  verifyFormat("promise.then([],\n"
+               "             function success() {\n"
+               "               doFoo();\n"
+               "               doBar();\n"
+               "             },\n"
+               "             function error() {\n"
+               "               doFoo();\n"
+               "               doBaz();\n"
+               "             });\n");
 }
 
 TEST_F(FormatTestJS, ReturnStatements) {
diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp
index 6506a6d..bfd5025 100644
--- a/unittests/Format/FormatTestProto.cpp
+++ b/unittests/Format/FormatTestProto.cpp
@@ -47,6 +47,9 @@
                "  required int32 field1 = 1;\n"
                "}");
   verifyFormat("message SomeMessage {\n"
+               "  required .absolute.Reference field1 = 1;\n"
+               "}");
+  verifyFormat("message SomeMessage {\n"
                "  required int32 field1 = 1;\n"
                "  optional string field2 = 2 [default = \"2\"]\n"
                "}");
diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index 3d30352..2d75b52 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -20,7 +20,6 @@
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
-#include "llvm/Config/config.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -42,7 +41,7 @@
                          bool Complain) override { }
 
   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
-    { return 0; }
+    { return nullptr; }
   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
     { return 0; };
 };
@@ -58,7 +57,7 @@
       TargetOpts(new TargetOptions) 
   {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, &*TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
   }
 
   std::vector<Token> CheckLex(StringRef Source,
@@ -68,9 +67,9 @@
 
     VoidModuleLoader ModLoader;
     HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
-                            Target.getPtr());
+                            Target.get());
     Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
-                    HeaderInfo, ModLoader, /*IILookup =*/0,
+                    HeaderInfo, ModLoader, /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
     PP.EnterMainSourceFile();
@@ -109,7 +108,7 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> Target;
 };
 
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index cceebea..a1af754 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -48,7 +48,7 @@
                          bool Complain) override { }
 
   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
-    { return 0; }
+    { return nullptr; }
   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
     { return 0; };
 };
@@ -116,14 +116,12 @@
 class PPCallbacksTest : public ::testing::Test {
 protected:
   PPCallbacksTest()
-    : FileMgr(FileMgrOpts),
-      DiagID(new DiagnosticIDs()),
-      DiagOpts(new DiagnosticOptions()),
-      Diags(DiagID, DiagOpts.getPtr(), new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr) {
-    TargetOpts = new TargetOptions();
+      : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
+        DiagOpts(new DiagnosticOptions()),
+        Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
+        SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, &*TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
   }
 
   FileSystemOptions FileMgrOpts;
@@ -133,7 +131,7 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> Target;
 
   // Register a header path as a known file and add its location
@@ -169,12 +167,12 @@
 
     IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts = new HeaderSearchOptions();
     HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts,
-                            Target.getPtr());
+                            Target.get());
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
 
     IntrusiveRefCntPtr<PreprocessorOptions> PPOpts = new PreprocessorOptions();
     Preprocessor PP(PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader,
-                    /*IILookup =*/0,
+                    /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
     InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks;
@@ -204,10 +202,10 @@
 
     VoidModuleLoader ModLoader;
     HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, 
-                            OpenCLLangOpts, Target.getPtr());
+                            OpenCLLangOpts, Target.get());
 
     Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts, SourceMgr,
-                    HeaderInfo, ModLoader, /*IILookup =*/0,
+                    HeaderInfo, ModLoader, /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
 
diff --git a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index f7ed8e5..e63106c 100644
--- a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -20,7 +20,6 @@
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
-#include "llvm/Config/config.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -39,7 +38,7 @@
       TargetOpts(new TargetOptions)
   {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, &*TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
   }
 
   FileSystemOptions FileMgrOpts;
@@ -48,7 +47,7 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> Target;
 };
 
@@ -66,7 +65,7 @@
                          bool Complain) override { }
 
   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
-    { return 0; }
+    { return nullptr; }
   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
     { return 0; };
 };
@@ -96,10 +95,10 @@
 
   VoidModuleLoader ModLoader;
   HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
-                          Target.getPtr());
+                          Target.get());
   Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
                   HeaderInfo, ModLoader,
-                  /*IILookup =*/0,
+                  /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
   PPConditionalDirectiveRecord *
diff --git a/unittests/Sema/ExternalSemaSourceTest.cpp b/unittests/Sema/ExternalSemaSourceTest.cpp
index 7cb5af1..bc0d632 100644
--- a/unittests/Sema/ExternalSemaSourceTest.cpp
+++ b/unittests/Sema/ExternalSemaSourceTest.cpp
@@ -49,7 +49,7 @@
 
 public:
   NamespaceDiagnosticWatcher(StringRef From, StringRef To)
-      : Chained(NULL), FromNS(From), ToNS("'"), SeenCount(0) {
+      : Chained(nullptr), FromNS(From), ToNS("'"), SeenCount(0) {
     ToNS.append(To);
     ToNS.append("'");
   }
@@ -95,11 +95,11 @@
 
 public:
   NamespaceTypoProvider(StringRef From, StringRef To)
-      : CorrectFrom(From), CorrectTo(To), CurrentSema(NULL), CallCount(0) {}
+      : CorrectFrom(From), CorrectTo(To), CurrentSema(nullptr), CallCount(0) {}
 
   virtual void InitializeSema(Sema &S) { CurrentSema = &S; }
 
-  virtual void ForgetSema() { CurrentSema = NULL; }
+  virtual void ForgetSema() { CurrentSema = nullptr; }
 
   virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
                                      int LookupKind, Scope *S, CXXScopeSpec *SS,
@@ -109,17 +109,17 @@
                                      const ObjCObjectPointerType *OPT) {
     ++CallCount;
     if (CurrentSema && Typo.getName().getAsString() == CorrectFrom) {
-      DeclContext *DestContext = NULL;
+      DeclContext *DestContext = nullptr;
       ASTContext &Context = CurrentSema->getASTContext();
-      if (SS != NULL)
+      if (SS)
         DestContext = CurrentSema->computeDeclContext(*SS, EnteringContext);
-      if (DestContext == NULL)
+      if (!DestContext)
         DestContext = Context.getTranslationUnitDecl();
       IdentifierInfo *ToIdent =
           CurrentSema->getPreprocessor().getIdentifierInfo(CorrectTo);
       NamespaceDecl *NewNamespace =
           NamespaceDecl::Create(Context, DestContext, false, Typo.getBeginLoc(),
-                                Typo.getLoc(), ToIdent, NULL);
+                                Typo.getLoc(), ToIdent, nullptr);
       DestContext->addDecl(NewNamespace);
       TypoCorrection Correction(ToIdent);
       Correction.addCorrectionDecl(NewNamespace);
@@ -149,7 +149,7 @@
   virtual void ExecuteAction() {
     CompilerInstance &CI = getCompilerInstance();
     ASSERT_FALSE(CI.hasSema());
-    CI.createSema(getTranslationUnitKind(), NULL);
+    CI.createSema(getTranslationUnitKind(), nullptr);
     ASSERT_TRUE(CI.hasDiagnostics());
     DiagnosticsEngine &Diagnostics = CI.getDiagnostics();
     DiagnosticConsumer *Client = Diagnostics.getClient();
diff --git a/unittests/Tooling/CommentHandlerTest.cpp b/unittests/Tooling/CommentHandlerTest.cpp
index f0f7797..117dfc3 100644
--- a/unittests/Tooling/CommentHandlerTest.cpp
+++ b/unittests/Tooling/CommentHandlerTest.cpp
@@ -28,7 +28,7 @@
   typedef TestVisitor<CommentHandlerVisitor> base;
 
 public:
-  CommentHandlerVisitor() : base(), PP(0), Verified(false) { }
+  CommentHandlerVisitor() : base(), PP(nullptr), Verified(false) {}
 
   ~CommentHandlerVisitor() {
     EXPECT_TRUE(Verified) << "CommentVerifier not accessed";
diff --git a/unittests/Tooling/CompilationDatabaseTest.cpp b/unittests/Tooling/CompilationDatabaseTest.cpp
index 9f078f4..8866e75 100644
--- a/unittests/Tooling/CompilationDatabaseTest.cpp
+++ b/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -22,8 +22,8 @@
 
 static void expectFailure(StringRef JSONDatabase, StringRef Explanation) {
   std::string ErrorMessage;
-  EXPECT_EQ(NULL, JSONCompilationDatabase::loadFromBuffer(JSONDatabase,
-                                                          ErrorMessage))
+  EXPECT_EQ(nullptr, JSONCompilationDatabase::loadFromBuffer(JSONDatabase,
+                                                             ErrorMessage))
     << "Expected an error because of: " << Explanation.str();
 }
 
@@ -434,7 +434,7 @@
 TEST(ParseFixedCompilationDatabase, ReturnsNullOnEmptyArgumentList) {
   int Argc = 0;
   std::unique_ptr<FixedCompilationDatabase> Database(
-      FixedCompilationDatabase::loadFromCommandLine(Argc, NULL));
+      FixedCompilationDatabase::loadFromCommandLine(Argc, nullptr));
   EXPECT_FALSE(Database);
   EXPECT_EQ(0, Argc);
 }
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 837a15f..a1a93a5 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -531,6 +531,15 @@
       TypeLocVisitor::Lang_C));
 }
 
+TEST(RecursiveASTVisitor, VisitsObjCPropertyType) {
+  TypeLocVisitor Visitor;
+  Visitor.ExpectMatch("NSNumber", 2, 33);
+  EXPECT_TRUE(Visitor.runOver(
+      "@class NSNumber; \n"
+      "@interface A @property (retain) NSNumber *x; @end\n",
+      TypeLocVisitor::Lang_OBJC));
+}
+
 TEST(RecursiveASTVisitor, VisitsLambdaExpr) {
   LambdaExprVisitor Visitor;
   Visitor.ExpectMatch("", 1, 12);
@@ -552,6 +561,16 @@
                               LambdaDefaultCaptureVisitor::Lang_CXX11));
 }
 
+TEST(RecursiveASTVisitor, VisitsCopyExprOfBlockDeclCapture) {
+  DeclRefExprVisitor Visitor;
+  Visitor.ExpectMatch("x", 3, 24);
+  EXPECT_TRUE(Visitor.runOver("void f(int(^)(int)); \n"
+                              "void g() { \n"
+                              "  f([&](int x){ return x; }); \n"
+                              "}",
+                              DeclRefExprVisitor::Lang_OBJCXX11));
+}
+
 // Checks for lambda classes that are not marked as implicitly-generated.
 // (There should be none.)
 class ClassVisitor : public ExpectedLocationVisitor<ClassVisitor> {
diff --git a/unittests/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp
index b1ed3c7..ddb974a 100644
--- a/unittests/Tooling/RefactoringTest.cpp
+++ b/unittests/Tooling/RefactoringTest.cpp
@@ -218,7 +218,7 @@
                                                 E = TemporaryFiles.end();
          I != E; ++I) {
       llvm::StringRef Name = I->second;
-      llvm::error_code EC = llvm::sys::fs::remove(Name);
+      std::error_code EC = llvm::sys::fs::remove(Name);
       (void)EC;
       assert(!EC);
     }
@@ -227,8 +227,7 @@
   FileID createFile(llvm::StringRef Name, llvm::StringRef Content) {
     SmallString<1024> Path;
     int FD;
-    llvm::error_code EC =
-        llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
+    std::error_code EC = llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
     assert(!EC);
     (void)EC;
 
@@ -236,7 +235,7 @@
     OutStream << Content;
     OutStream.close();
     const FileEntry *File = Context.Files.getFile(Path);
-    assert(File != NULL);
+    assert(File != nullptr);
 
     StringRef Found = TemporaryFiles.GetOrCreateValue(Name, Path.str()).second;
     assert(Found == Path);
@@ -253,7 +252,7 @@
     // FIXME: Figure out whether there is a way to get the SourceManger to
     // reopen the file.
     std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(
-        Context.Files.getBufferForFile(Path, NULL));
+        Context.Files.getBufferForFile(Path, nullptr));
     return FileBuffer->getBuffer();
   }
 
diff --git a/unittests/Tooling/RewriterTestContext.h b/unittests/Tooling/RewriterTestContext.h
index f02ba1a..fe108ad 100644
--- a/unittests/Tooling/RewriterTestContext.h
+++ b/unittests/Tooling/RewriterTestContext.h
@@ -48,12 +48,11 @@
   ~RewriterTestContext() {}
 
   FileID createInMemoryFile(StringRef Name, StringRef Content) {
-    const llvm::MemoryBuffer *Source =
-      llvm::MemoryBuffer::getMemBuffer(Content);
+    llvm::MemoryBuffer *Source = llvm::MemoryBuffer::getMemBuffer(Content);
     const FileEntry *Entry =
       Files.getVirtualFile(Name, Source->getBufferSize(), 0);
     Sources.overrideFileContents(Entry, Source);
-    assert(Entry != NULL);
+    assert(Entry != nullptr);
     return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
   }
 
@@ -62,8 +61,7 @@
   FileID createOnDiskFile(StringRef Name, StringRef Content) {
     SmallString<1024> Path;
     int FD;
-    llvm::error_code EC =
-        llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
+    std::error_code EC = llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
     assert(!EC);
     (void)EC;
 
@@ -71,7 +69,7 @@
     OutStream << Content;
     OutStream.close();
     const FileEntry *File = Files.getFile(Path);
-    assert(File != NULL);
+    assert(File != nullptr);
 
     StringRef Found = TemporaryFiles.GetOrCreateValue(Name, Path.str()).second;
     assert(Found == Path);
@@ -103,7 +101,7 @@
     // FIXME: Figure out whether there is a way to get the SourceManger to
     // reopen the file.
     std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(
-        Files.getBufferForFile(Path, NULL));
+        Files.getBufferForFile(Path, nullptr));
     return FileBuffer->getBuffer();
   }
 
diff --git a/unittests/Tooling/TestVisitor.h b/unittests/Tooling/TestVisitor.h
index ec751c3..205a0aa 100644
--- a/unittests/Tooling/TestVisitor.h
+++ b/unittests/Tooling/TestVisitor.h
@@ -39,7 +39,14 @@
 
   virtual ~TestVisitor() { }
 
-  enum Language { Lang_C, Lang_CXX98, Lang_CXX11, Lang_CXX=Lang_CXX98 };
+  enum Language {
+    Lang_C,
+    Lang_CXX98,
+    Lang_CXX11,
+    Lang_OBJC,
+    Lang_OBJCXX11,
+    Lang_CXX = Lang_CXX98
+  };
 
   /// \brief Runs the current AST visitor over the given code.
   bool runOver(StringRef Code, Language L = Lang_CXX) {
@@ -48,6 +55,12 @@
       case Lang_C: Args.push_back("-std=c99"); break;
       case Lang_CXX98: Args.push_back("-std=c++98"); break;
       case Lang_CXX11: Args.push_back("-std=c++11"); break;
+      case Lang_OBJC: Args.push_back("-ObjC"); break;
+      case Lang_OBJCXX11:
+        Args.push_back("-ObjC++");
+        Args.push_back("-std=c++11");
+        Args.push_back("-fblocks");
+        break;
     }
     return tooling::runToolOnCodeWithArgs(CreateTestAction(), Code, Args);
   }
diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp
index 2d055e7..9aede04 100644
--- a/unittests/Tooling/ToolingTest.cpp
+++ b/unittests/Tooling/ToolingTest.cpp
@@ -17,7 +17,7 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 #include "gtest/gtest.h"
 #include <string>
 
@@ -121,12 +121,12 @@
   std::unique_ptr<FrontendActionFactory> Factory(
       newFrontendActionFactory<SyntaxOnlyAction>());
   std::unique_ptr<FrontendAction> Action(Factory->create());
-  EXPECT_TRUE(Action.get() != NULL);
+  EXPECT_TRUE(Action.get() != nullptr);
 }
 
 struct IndependentFrontendActionCreator {
   ASTConsumer *newASTConsumer() {
-    return new FindTopLevelDeclConsumer(NULL);
+    return new FindTopLevelDeclConsumer(nullptr);
   }
 };
 
@@ -135,7 +135,7 @@
   std::unique_ptr<FrontendActionFactory> Factory(
       newFrontendActionFactory(&Creator));
   std::unique_ptr<FrontendAction> Action(Factory->create());
-  EXPECT_TRUE(Action.get() != NULL);
+  EXPECT_TRUE(Action.get() != nullptr);
 }
 
 TEST(ToolInvocation, TestMapVirtualFile) {
@@ -147,7 +147,7 @@
   Args.push_back("-fsyntax-only");
   Args.push_back("test.cpp");
   clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
-                                            Files.getPtr());
+                                            Files.get());
   Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
   Invocation.mapVirtualFile("def/abc", "\n");
   EXPECT_TRUE(Invocation.run());
@@ -166,7 +166,7 @@
   Args.push_back("-fsyntax-only");
   Args.push_back("test.cpp");
   clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
-                                            Files.getPtr());
+                                            Files.get());
   Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
   Invocation.mapVirtualFile("def/abc", "\n");
   // Add a module.map file in the include directory of our header, so we trigger
diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
index 213222c..ef162bc 100644
--- a/unittests/libclang/LibclangTest.cpp
+++ b/unittests/libclang/LibclangTest.cpp
@@ -9,24 +9,32 @@
 
 #include "clang-c/Index.h"
 #include "gtest/gtest.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <fstream>
+#include <set>
+#define DEBUG_TYPE "libclang-test"
 
 TEST(libclang, clang_parseTranslationUnit2_InvalidArgs) {
   EXPECT_EQ(CXError_InvalidArguments,
-            clang_parseTranslationUnit2(0, 0, 0, 0, 0, 0, 0, 0));
+            clang_parseTranslationUnit2(nullptr, nullptr, nullptr, 0, nullptr,
+                                        0, 0, nullptr));
 }
 
 TEST(libclang, clang_createTranslationUnit_InvalidArgs) {
-  EXPECT_EQ(0, clang_createTranslationUnit(0, 0));
+  EXPECT_EQ(nullptr, clang_createTranslationUnit(nullptr, nullptr));
 }
 
 TEST(libclang, clang_createTranslationUnit2_InvalidArgs) {
   EXPECT_EQ(CXError_InvalidArguments,
-            clang_createTranslationUnit2(0, 0, 0));
+            clang_createTranslationUnit2(nullptr, nullptr, nullptr));
 
   CXTranslationUnit TU = reinterpret_cast<CXTranslationUnit>(1);
   EXPECT_EQ(CXError_InvalidArguments,
-            clang_createTranslationUnit2(0, 0, &TU));
-  EXPECT_EQ(0, TU);
+            clang_createTranslationUnit2(nullptr, nullptr, &TU));
+  EXPECT_EQ(nullptr, TU);
 }
 
 namespace {
@@ -107,7 +115,7 @@
 }
 
 TEST(libclang, VirtualFileOverlay_InvalidArgs) {
-  TestVFO T(NULL);
+  TestVFO T(nullptr);
   T.mapError("/path/./virtual/../foo.h", "/real/foo.h",
              CXError_InvalidArguments);
 }
@@ -330,3 +338,120 @@
   free(BufPtr);
   clang_ModuleMapDescriptor_dispose(MMD);
 }
+
+class LibclangReparseTest : public ::testing::Test {
+  std::set<std::string> Files;
+public:
+  std::string TestDir;
+  CXIndex Index;
+  CXTranslationUnit ClangTU;
+  unsigned TUFlags;
+
+  void SetUp() {
+    llvm::SmallString<256> Dir;
+    ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("libclang-test", Dir));
+    TestDir = Dir.str();
+    TUFlags = CXTranslationUnit_DetailedPreprocessingRecord |
+              clang_defaultEditingTranslationUnitOptions();
+    Index = clang_createIndex(0, 0);
+  }
+  void TearDown() {
+    clang_disposeTranslationUnit(ClangTU);
+    clang_disposeIndex(Index);
+    for (const std::string &Path : Files)
+      llvm::sys::fs::remove(Path);
+    llvm::sys::fs::remove(TestDir);
+  }
+  void WriteFile(std::string &Filename, const std::string &Contents) {
+    if (!llvm::sys::path::is_absolute(Filename)) {
+      llvm::SmallString<256> Path(TestDir);
+      llvm::sys::path::append(Path, Filename);
+      Filename = Path.str();
+      Files.insert(Filename);
+    }
+    std::ofstream OS(Filename);
+    OS << Contents;
+  }
+  void DisplayDiagnostics() {
+    unsigned NumDiagnostics = clang_getNumDiagnostics(ClangTU);
+    for (unsigned i = 0; i < NumDiagnostics; ++i) {
+      auto Diag = clang_getDiagnostic(ClangTU, i);
+      DEBUG(llvm::dbgs() << clang_getCString(clang_formatDiagnostic(
+          Diag, clang_defaultDiagnosticDisplayOptions())) << "\n");
+      clang_disposeDiagnostic(Diag);
+    }
+  }
+  bool ReparseTU(unsigned num_unsaved_files, CXUnsavedFile* unsaved_files) {
+    if (clang_reparseTranslationUnit(ClangTU, num_unsaved_files, unsaved_files,
+                                     clang_defaultReparseOptions(ClangTU))) {
+      DEBUG(llvm::dbgs() << "Reparse failed\n");
+      return false;
+    }
+    DisplayDiagnostics();
+    return true;
+  }
+};
+
+
+TEST_F(LibclangReparseTest, Reparse) {
+  const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
+  const char *HeaderBottom = "\n};\n#endif\n";
+  const char *CppFile = "#include \"HeaderFile.h\"\nint main() {"
+                         " Foo foo; foo.bar = 7; foo.baz = 8; }\n";
+  std::string HeaderName = "HeaderFile.h";
+  std::string CppName = "CppFile.cpp";
+  WriteFile(CppName, CppFile);
+  WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
+
+  ClangTU = clang_parseTranslationUnit(Index, CppName.c_str(), nullptr, 0,
+                                       nullptr, 0, TUFlags);
+  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+  DisplayDiagnostics();
+
+  // Immedaitely reparse.
+  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+
+  std::string NewHeaderContents =
+      std::string(HeaderTop) + "int baz;" + HeaderBottom;
+  WriteFile(HeaderName, NewHeaderContents);
+
+  // Reparse after fix.
+  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+  EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
+}
+
+TEST_F(LibclangReparseTest, ReparseWithModule) {
+  const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
+  const char *HeaderBottom = "\n};\n#endif\n";
+  const char *MFile = "#include \"HeaderFile.h\"\nint main() {"
+                         " struct Foo foo; foo.bar = 7; foo.baz = 8; }\n";
+  const char *ModFile = "module A { header \"HeaderFile.h\" }\n";
+  std::string HeaderName = "HeaderFile.h";
+  std::string MName = "MFile.m";
+  std::string ModName = "module.modulemap";
+  WriteFile(MName, MFile);
+  WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
+  WriteFile(ModName, ModFile);
+
+  std::string ModulesCache = std::string("-fmodules-cache-path=") + TestDir;
+  const char *Args[] = { "-fmodules", ModulesCache.c_str(),
+                         "-I", TestDir.c_str() };
+  int NumArgs = sizeof(Args) / sizeof(Args[0]);
+  ClangTU = clang_parseTranslationUnit(Index, MName.c_str(), Args, NumArgs,
+                                       nullptr, 0, TUFlags);
+  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+  DisplayDiagnostics();
+
+  // Immedaitely reparse.
+  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+
+  std::string NewHeaderContents =
+      std::string(HeaderTop) + "int baz;" + HeaderBottom;
+  WriteFile(HeaderName, NewHeaderContents);
+
+  // Reparse after fix.
+  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+  EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
+}
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index c409218..7ae8b74 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -41,7 +41,7 @@
 
     assert(V != "GCC" && "Given a GCC spelling, which means this hasn't been"
            "flattened!");
-    if (V == "CXX11")
+    if (V == "CXX11" || V == "Pragma")
       NS = Spelling.getValueAsString("Namespace");
     bool Unset;
     K = Spelling.getValueAsBitOrUnset("KnownToGCC", Unset);
@@ -484,9 +484,11 @@
          << "Type(), Record);\n";
     }
     void writeValue(raw_ostream &OS) const override {
-      OS << "\";\n"
-         << "  " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"
-         << "  OS << \"";
+      OS << "\";\n";
+      OS << "    assert(is" << getLowerName() << "Expr && " << getLowerName()
+         << "Expr != nullptr);\n";
+      OS << "    " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n";
+      OS << "    OS << \"";
     }
     void writeDump(raw_ostream &OS) const override {
     }
@@ -859,7 +861,7 @@
       OS << "        ExprResult " << "Result = S.SubstExpr("
          << "A->get" << getUpperName() << "(), TemplateArgs);\n";
       OS << "        tempInst" << getUpperName() << " = "
-         << "Result.takeAs<Expr>();\n";
+         << "Result.getAs<Expr>();\n";
       OS << "      }\n";
     }
 
@@ -911,7 +913,7 @@
          << "_end();\n";
       OS << "        for (; I != E; ++I, ++TI) {\n";
       OS << "          ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
-      OS << "          *TI = Result.takeAs<Expr>();\n";
+      OS << "          *TI = Result.getAs<Expr>();\n";
       OS << "        }\n";
       OS << "      }\n";
     }
@@ -1053,7 +1055,7 @@
   OS << "void " << R.getName() << "Attr::printPretty("
     << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
 
-  if (Spellings.size() == 0) {
+  if (Spellings.empty()) {
     OS << "}\n\n";
     return;
   }
@@ -1080,7 +1082,7 @@
       Prefix = " [[";
       Suffix = "]]";
       std::string Namespace = Spellings[I].nameSpace();
-      if (Namespace != "") {
+      if (!Namespace.empty()) {
         Spelling += Namespace;
         Spelling += "::";
       }
@@ -1090,6 +1092,14 @@
     } else if (Variety == "Keyword") {
       Prefix = " ";
       Suffix = "";
+    } else if (Variety == "Pragma") {
+      Prefix = "#pragma ";
+      Suffix = "\n";
+      std::string Namespace = Spellings[I].nameSpace();
+      if (!Namespace.empty()) {
+        Spelling += Namespace;
+        Spelling += " ";
+      }
     } else {
       llvm_unreachable("Unknown attribute syntax variety!");
     }
@@ -1100,6 +1110,14 @@
       "  case " << I << " : {\n"
       "    OS << \"" + Prefix.str() + Spelling.str();
 
+    if (Variety == "Pragma") {
+      OS << " \";\n";
+      OS << "    printPrettyPragma(OS, Policy);\n";
+      OS << "    break;\n";
+      OS << "  }\n";
+      continue;
+    }
+
     if (!Args.empty())
       OS << "(";
     if (Spelling == "availability") {
@@ -1553,12 +1571,16 @@
 
     OS << R.getName() << "Attr *" << R.getName()
        << "Attr::clone(ASTContext &C) const {\n";
-    OS << "  return new (C) " << R.getName() << "Attr(getLocation(), C";
+    OS << "  auto *A = new (C) " << R.getName() << "Attr(getLocation(), C";
     for (auto const &ai : Args) {
       OS << ", ";
       ai->writeCloneArgs(OS);
     }
-    OS << ", getSpellingListIndex());\n}\n\n";
+    OS << ", getSpellingListIndex());\n";
+    OS << "  A->Inherited = Inherited;\n";
+    OS << "  A->IsPackExpansion = IsPackExpansion;\n";
+    OS << "  A->Implicit = Implicit;\n";
+    OS << "  return A;\n}\n\n";
 
     writePrettyPrintFunction(R, Args, OS);
     writeGetSpellingFunction(R, OS);
@@ -1649,8 +1671,7 @@
 
   OS << "  switch (Kind) {\n";
   OS << "  default:\n";
-  OS << "    assert(0 && \"Unknown attribute!\");\n";
-  OS << "    break;\n";
+  OS << "    llvm_unreachable(\"Unknown attribute!\");\n";
   for (const auto *Attr : Attrs) {
     const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
@@ -1776,7 +1797,7 @@
   // Separate all of the attributes out into four group: generic, C++11, GNU,
   // and declspecs. Then generate a big switch statement for each of them.
   std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-  std::vector<Record *> Declspec, GNU;
+  std::vector<Record *> Declspec, GNU, Pragma;
   std::map<std::string, std::vector<Record *>> CXX;
 
   // Walk over the list of all attributes, and split them out based on the
@@ -1789,9 +1810,10 @@
         GNU.push_back(R);
       else if (Variety == "Declspec")
         Declspec.push_back(R);
-      else if (Variety == "CXX11") {
+      else if (Variety == "CXX11")
         CXX[SI.nameSpace()].push_back(R);
-      }
+      else if (Variety == "Pragma")
+        Pragma.push_back(R);
     }
   }
 
@@ -1805,6 +1827,9 @@
   OS << "case AttrSyntax::Declspec:\n";
   OS << "  return llvm::StringSwitch<bool>(Name)\n";
   GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec");
+  OS << "case AttrSyntax::Pragma:\n";
+  OS << "  return llvm::StringSwitch<bool>(Name)\n";
+  GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
   OS << "case AttrSyntax::CXX: {\n";
   // C++11-style attributes are further split out based on the Scope.
   for (std::map<std::string, std::vector<Record *>>::iterator I = CXX.begin(),
@@ -1840,17 +1865,17 @@
     std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
     OS << "  case AT_" << I.first << ": {\n";
     for (unsigned I = 0; I < Spellings.size(); ++ I) {
-      OS << "    if (Name == \""
-        << Spellings[I].name() << "\" && "
-        << "SyntaxUsed == "
-        << StringSwitch<unsigned>(Spellings[I].variety())
-          .Case("GNU", 0)
-          .Case("CXX11", 1)
-          .Case("Declspec", 2)
-          .Case("Keyword", 3)
-          .Default(0)
-        << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
-        << "        return " << I << ";\n";
+      OS << "    if (Name == \"" << Spellings[I].name() << "\" && "
+         << "SyntaxUsed == "
+         << StringSwitch<unsigned>(Spellings[I].variety())
+                .Case("GNU", 0)
+                .Case("CXX11", 1)
+                .Case("Declspec", 2)
+                .Case("Keyword", 3)
+                .Case("Pragma", 4)
+                .Default(0)
+         << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
+         << "        return " << I << ";\n";
     }
 
     OS << "    break;\n";
@@ -2470,7 +2495,7 @@
   emitSourceFileHeader("Attribute name matcher", OS);
 
   std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-  std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords;
+  std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords, Pragma;
   std::set<std::string> Seen;
   for (const auto *A : Attrs) {
     const Record &Attr = *A;
@@ -2513,6 +2538,8 @@
           Matches = &Declspec;
         else if (Variety == "Keyword")
           Matches = &Keywords;
+        else if (Variety == "Pragma")
+          Matches = &Pragma;
 
         assert(Matches && "Unsupported spelling variety found");
 
@@ -2537,6 +2564,8 @@
   StringMatcher("Name", CXX11, OS).Emit();
   OS << "  } else if (AttributeList::AS_Keyword == Syntax) {\n";
   StringMatcher("Name", Keywords, OS).Emit();
+  OS << "  } else if (AttributeList::AS_Pragma == Syntax) {\n";
+  StringMatcher("Name", Pragma, OS).Emit();
   OS << "  }\n";
   OS << "  return AttributeList::UnknownAttribute;\n"
      << "}\n";
@@ -2642,7 +2671,8 @@
   GNU = 1 << 0,
   CXX11 = 1 << 1,
   Declspec = 1 << 2,
-  Keyword = 1 << 3
+  Keyword = 1 << 3,
+  Pragma = 1 << 4
 };
 
 static void WriteDocumentation(const DocumentationData &Doc,
@@ -2687,10 +2717,11 @@
   unsigned SupportedSpellings = 0;
   for (const auto &I : Spellings) {
     SpellingKind Kind = StringSwitch<SpellingKind>(I.variety())
-      .Case("GNU", GNU)
-      .Case("CXX11", CXX11)
-      .Case("Declspec", Declspec)
-      .Case("Keyword", Keyword);
+                            .Case("GNU", GNU)
+                            .Case("CXX11", CXX11)
+                            .Case("Declspec", Declspec)
+                            .Case("Keyword", Keyword)
+                            .Case("Pragma", Pragma);
 
     // Mask in the supported spelling.
     SupportedSpellings |= Kind;
@@ -2725,7 +2756,8 @@
 
   // List what spelling syntaxes the attribute supports.
   OS << ".. csv-table:: Supported Syntaxes\n";
-  OS << "   :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\"\n\n";
+  OS << "   :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\",";
+  OS << " \"Pragma\"\n\n";
   OS << "   \"";
   if (SupportedSpellings & GNU) OS << "X";
   OS << "\",\"";
@@ -2734,6 +2766,8 @@
   if (SupportedSpellings & Declspec) OS << "X";
   OS << "\",\"";
   if (SupportedSpellings & Keyword) OS << "X";
+  OS << "\", \"";
+  if (SupportedSpellings & Pragma) OS << "X";
   OS << "\"\n\n";
 
   // If the attribute is deprecated, print a message about it, and possibly
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp
index b4cc706..e517755 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -358,8 +358,9 @@
 }
 
 bool InferPedantic::isOffByDefault(const Record *Diag) {
-  const std::string &DefMap = Diag->getValueAsDef("DefaultMapping")->getName();
-  return DefMap == "MAP_IGNORE";
+  const std::string &DefSeverity =
+      Diag->getValueAsDef("DefaultSeverity")->getValueAsString("Name");
+  return DefSeverity == "Ignored";
 }
 
 bool InferPedantic::groupInPedantic(const Record *Group, bool increment) {
@@ -538,7 +539,8 @@
 
     OS << "DIAG(" << R.getName() << ", ";
     OS << R.getValueAsDef("Class")->getName();
-    OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName();
+    OS << ", (unsigned)diag::Severity::"
+       << R.getValueAsDef("DefaultSeverity")->getValueAsString("Name");
 
     // Description string.
     OS << ", \"";
@@ -569,8 +571,7 @@
     else
       OS << ", false";
 
-    // Default warning show in system header bit.
-    if (R.getValueAsBit("WarningShowInSystemHeader"))
+    if (R.getValueAsBit("ShowInSystemHeader"))
       OS << ", true";
     else
       OS << ", false";
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 6dfdcb3..d7e418a 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -18,8 +18,9 @@
 // CodeGen library.
 //
 // Additional validation code can be generated by this file when runHeader() is
-// called, rather than the normal run() entry point.  A complete set of tests
-// for Neon intrinsics can be generated by calling the runTests() entry point.
+// called, rather than the normal run() entry point.
+//
+// See also the documentation in include/clang/Basic/arm_neon.td.
 //
 //===----------------------------------------------------------------------===//
 
@@ -31,318 +32,477 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/SetTheory.h"
 #include "llvm/TableGen/TableGenBackend.h"
 #include <string>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <algorithm>
 using namespace llvm;
 
-enum OpKind {
-  OpNone,
-  OpUnavailable,
-  OpAdd,
-  OpAddl,
-  OpAddlHi,
-  OpAddw,
-  OpAddwHi,
-  OpSub,
-  OpSubl,
-  OpSublHi,
-  OpSubw,
-  OpSubwHi,
-  OpMul,
-  OpMla,
-  OpMlal,
-  OpMullHi,
-  OpMullHiP64,
-  OpMullHiN,
-  OpMlalHi,
-  OpMlalHiN,
-  OpMls,
-  OpMlsl,
-  OpMlslHi,
-  OpMlslHiN,
-  OpMulN,
-  OpMlaN,
-  OpMlsN,
-  OpFMlaN,
-  OpFMlsN,
-  OpMlalN,
-  OpMlslN,
-  OpMulLane,
-  OpMulXLane,
-  OpMullLane,
-  OpMullHiLane,
-  OpMlaLane,
-  OpMlsLane,
-  OpMlalLane,
-  OpMlalHiLane,
-  OpMlslLane,
-  OpMlslHiLane,
-  OpQDMullLane,
-  OpQDMullHiLane,
-  OpQDMlalLane,
-  OpQDMlalHiLane,
-  OpQDMlslLane,
-  OpQDMlslHiLane,
-  OpQDMulhLane,
-  OpQRDMulhLane,
-  OpFMSLane,
-  OpFMSLaneQ,
-  OpTrn1,
-  OpZip1,
-  OpUzp1,
-  OpTrn2,
-  OpZip2,
-  OpUzp2,
-  OpEq,
-  OpGe,
-  OpLe,
-  OpGt,
-  OpLt,
-  OpNeg,
-  OpNot,
-  OpAnd,
-  OpOr,
-  OpXor,
-  OpAndNot,
-  OpOrNot,
-  OpCast,
-  OpConcat,
-  OpDup,
-  OpDupLane,
-  OpHi,
-  OpLo,
-  OpSelect,
-  OpRev16,
-  OpRev32,
-  OpRev64,
-  OpXtnHi,
-  OpSqxtunHi,
-  OpQxtnHi,
-  OpFcvtnHi,
-  OpFcvtlHi,
-  OpFcvtxnHi,
-  OpReinterpret,
-  OpAddhnHi,
-  OpRAddhnHi,
-  OpSubhnHi,
-  OpRSubhnHi,
-  OpAbdl,
-  OpAbdlHi,
-  OpAba,
-  OpAbal,
-  OpAbalHi,
-  OpQDMullHi,
-  OpQDMullHiN,
-  OpQDMlalHi,
-  OpQDMlalHiN,
-  OpQDMlslHi,
-  OpQDMlslHiN,
-  OpDiv,
-  OpLongHi,
-  OpNarrowHi,
-  OpMovlHi,
-  OpCopyLane,
-  OpCopyQLane,
-  OpCopyLaneQ,
-  OpScalarMulLane,
-  OpScalarMulLaneQ,
-  OpScalarMulXLane,
-  OpScalarMulXLaneQ,
-  OpScalarVMulXLane,
-  OpScalarVMulXLaneQ,
-  OpScalarQDMullLane,
-  OpScalarQDMullLaneQ,
-  OpScalarQDMulHiLane,
-  OpScalarQDMulHiLaneQ,
-  OpScalarQRDMulHiLane,
-  OpScalarQRDMulHiLaneQ,
-  OpScalarGetLane,
-  OpScalarSetLane
-};
+namespace {
+
+// While globals are generally bad, this one allows us to perform assertions
+// liberally and somehow still trace them back to the def they indirectly
+// came from.
+static Record *CurrentRecord = nullptr;
+static void assert_with_loc(bool Assertion, const std::string &Str) {
+  if (!Assertion) {
+    if (CurrentRecord)
+      PrintFatalError(CurrentRecord->getLoc(), Str);
+    else
+      PrintFatalError(Str);
+  }
+}
 
 enum ClassKind {
   ClassNone,
-  ClassI,           // generic integer instruction, e.g., "i8" suffix
-  ClassS,           // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix
-  ClassW,           // width-specific instruction, e.g., "8" suffix
-  ClassB,           // bitcast arguments with enum argument to specify type
-  ClassL,           // Logical instructions which are op instructions
-                    // but we need to not emit any suffix for in our
-                    // tests.
-  ClassNoTest       // Instructions which we do not test since they are
-                    // not TRUE instructions.
+  ClassI,     // generic integer instruction, e.g., "i8" suffix
+  ClassS,     // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix
+  ClassW,     // width-specific instruction, e.g., "8" suffix
+  ClassB,     // bitcast arguments with enum argument to specify type
+  ClassL,     // Logical instructions which are op instructions
+              // but we need to not emit any suffix for in our
+              // tests.
+  ClassNoTest // Instructions which we do not test since they are
+              // not TRUE instructions.
 };
 
 /// NeonTypeFlags - Flags to identify the types for overloaded Neon
 /// builtins.  These must be kept in sync with the flags in
 /// include/clang/Basic/TargetBuiltins.h.
-namespace {
-class NeonTypeFlags {
-  enum {
-    EltTypeMask = 0xf,
-    UnsignedFlag = 0x10,
-    QuadFlag = 0x20
-  };
-  uint32_t Flags;
+namespace NeonTypeFlags {
+enum { EltTypeMask = 0xf, UnsignedFlag = 0x10, QuadFlag = 0x20 };
+
+enum EltType {
+  Int8,
+  Int16,
+  Int32,
+  Int64,
+  Poly8,
+  Poly16,
+  Poly64,
+  Poly128,
+  Float16,
+  Float32,
+  Float64
+};
+}
+
+class Intrinsic;
+class NeonEmitter;
+class Type;
+class Variable;
+
+//===----------------------------------------------------------------------===//
+// TypeSpec
+//===----------------------------------------------------------------------===//
+
+/// A TypeSpec is just a simple wrapper around a string, but gets its own type
+/// for strong typing purposes.
+///
+/// A TypeSpec can be used to create a type.
+class TypeSpec : public std::string {
+public:
+  static std::vector<TypeSpec> fromTypeSpecs(StringRef Str) {
+    std::vector<TypeSpec> Ret;
+    TypeSpec Acc;
+    for (char I : Str.str()) {
+      if (islower(I)) {
+        Acc.push_back(I);
+        Ret.push_back(TypeSpec(Acc));
+        Acc.clear();
+      } else {
+        Acc.push_back(I);
+      }
+    }
+    return Ret;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Type
+//===----------------------------------------------------------------------===//
+
+/// A Type. Not much more to say here.
+class Type {
+private:
+  TypeSpec TS;
+
+  bool Float, Signed, Void, Poly, Constant, Pointer;
+  // ScalarForMangling and NoManglingQ are really not suited to live here as
+  // they are not related to the type. But they live in the TypeSpec (not the
+  // prototype), so this is really the only place to store them.
+  bool ScalarForMangling, NoManglingQ;
+  unsigned Bitwidth, ElementBitwidth, NumVectors;
 
 public:
-  enum EltType {
-    Int8,
-    Int16,
-    Int32,
-    Int64,
-    Poly8,
-    Poly16,
-    Poly64,
-    Poly128,
-    Float16,
-    Float32,
-    Float64
-  };
+  Type()
+      : Float(false), Signed(false), Void(true), Poly(false), Constant(false),
+        Pointer(false), ScalarForMangling(false), NoManglingQ(false),
+        Bitwidth(0), ElementBitwidth(0), NumVectors(0) {}
 
-  NeonTypeFlags(unsigned F) : Flags(F) {}
-  NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
-    if (IsUnsigned)
-      Flags |= UnsignedFlag;
-    if (IsQuad)
-      Flags |= QuadFlag;
+  Type(TypeSpec TS, char CharMod)
+      : TS(TS), Float(false), Signed(false), Void(false), Poly(false),
+        Constant(false), Pointer(false), ScalarForMangling(false),
+        NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) {
+    applyModifier(CharMod);
   }
 
-  uint32_t getFlags() const { return Flags; }
-};
-} // end anonymous namespace
+  /// Returns a type representing "void".
+  static Type getVoid() { return Type(); }
 
-namespace {
-class NeonEmitter {
-  RecordKeeper &Records;
-  StringMap<OpKind> OpMap;
-  DenseMap<Record*, ClassKind> ClassMap;
+  bool operator==(const Type &Other) const { return str() == Other.str(); }
+  bool operator!=(const Type &Other) const { return !operator==(Other); }
+
+  //
+  // Query functions
+  //
+  bool isScalarForMangling() const { return ScalarForMangling; }
+  bool noManglingQ() const { return NoManglingQ; }
+
+  bool isPointer() const { return Pointer; }
+  bool isFloating() const { return Float; }
+  bool isInteger() const { return !Float && !Poly; }
+  bool isSigned() const { return Signed; }
+  bool isScalar() const { return NumVectors == 0; }
+  bool isVector() const { return NumVectors > 0; }
+  bool isFloat() const { return Float && ElementBitwidth == 32; }
+  bool isDouble() const { return Float && ElementBitwidth == 64; }
+  bool isHalf() const { return Float && ElementBitwidth == 16; }
+  bool isPoly() const { return Poly; }
+  bool isChar() const { return ElementBitwidth == 8; }
+  bool isShort() const { return !Float && ElementBitwidth == 16; }
+  bool isInt() const { return !Float && ElementBitwidth == 32; }
+  bool isLong() const { return !Float && ElementBitwidth == 64; }
+  bool isVoid() const { return Void; }
+  unsigned getNumElements() const { return Bitwidth / ElementBitwidth; }
+  unsigned getSizeInBits() const { return Bitwidth; }
+  unsigned getElementSizeInBits() const { return ElementBitwidth; }
+  unsigned getNumVectors() const { return NumVectors; }
+
+  //
+  // Mutator functions
+  //
+  void makeUnsigned() { Signed = false; }
+  void makeSigned() { Signed = true; }
+  void makeInteger(unsigned ElemWidth, bool Sign) {
+    Float = false;
+    Poly = false;
+    Signed = Sign;
+    ElementBitwidth = ElemWidth;
+  }
+  void makeScalar() {
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+  }
+  void makeOneVector() {
+    assert(isVector());
+    NumVectors = 1;
+  }
+  void doubleLanes() {
+    assert_with_loc(Bitwidth != 128, "Can't get bigger than 128!");
+    Bitwidth = 128;
+  }
+  void halveLanes() {
+    assert_with_loc(Bitwidth != 64, "Can't get smaller than 64!");
+    Bitwidth = 64;
+  }
+
+  /// Return the C string representation of a type, which is the typename
+  /// defined in stdint.h or arm_neon.h.
+  std::string str() const;
+
+  /// Return the string representation of a type, which is an encoded
+  /// string for passing to the BUILTIN() macro in Builtins.def.
+  std::string builtin_str() const;
+
+  /// Return the value in NeonTypeFlags for this type.
+  unsigned getNeonEnum() const;
+
+  /// Parse a type from a stdint.h or arm_neon.h typedef name,
+  /// for example uint32x2_t or int64_t.
+  static Type fromTypedefName(StringRef Name);
+
+private:
+  /// Creates the type based on the typespec string in TS.
+  /// Sets "Quad" to true if the "Q" or "H" modifiers were
+  /// seen. This is needed by applyModifier as some modifiers
+  /// only take effect if the type size was changed by "Q" or "H".
+  void applyTypespec(bool &Quad);
+  /// Applies a prototype modifier to the type.
+  void applyModifier(char Mod);
+};
+
+//===----------------------------------------------------------------------===//
+// Variable
+//===----------------------------------------------------------------------===//
+
+/// A variable is a simple class that just has a type and a name.
+class Variable {
+  Type T;
+  std::string N;
 
 public:
-  NeonEmitter(RecordKeeper &R) : Records(R) {
-    OpMap["OP_NONE"]  = OpNone;
-    OpMap["OP_UNAVAILABLE"] = OpUnavailable;
-    OpMap["OP_ADD"]   = OpAdd;
-    OpMap["OP_ADDL"]  = OpAddl;
-    OpMap["OP_ADDLHi"] = OpAddlHi;
-    OpMap["OP_ADDW"]  = OpAddw;
-    OpMap["OP_ADDWHi"] = OpAddwHi;
-    OpMap["OP_SUB"]   = OpSub;
-    OpMap["OP_SUBL"]  = OpSubl;
-    OpMap["OP_SUBLHi"] = OpSublHi;
-    OpMap["OP_SUBW"]  = OpSubw;
-    OpMap["OP_SUBWHi"] = OpSubwHi;
-    OpMap["OP_MUL"]   = OpMul;
-    OpMap["OP_MLA"]   = OpMla;
-    OpMap["OP_MLAL"]  = OpMlal;
-    OpMap["OP_MULLHi"]  = OpMullHi;
-    OpMap["OP_MULLHi_P64"]  = OpMullHiP64;
-    OpMap["OP_MULLHi_N"]  = OpMullHiN;
-    OpMap["OP_MLALHi"]  = OpMlalHi;
-    OpMap["OP_MLALHi_N"]  = OpMlalHiN;
-    OpMap["OP_MLS"]   = OpMls;
-    OpMap["OP_MLSL"]  = OpMlsl;
-    OpMap["OP_MLSLHi"] = OpMlslHi;
-    OpMap["OP_MLSLHi_N"] = OpMlslHiN;
-    OpMap["OP_MUL_N"] = OpMulN;
-    OpMap["OP_MLA_N"] = OpMlaN;
-    OpMap["OP_MLS_N"] = OpMlsN;
-    OpMap["OP_FMLA_N"] = OpFMlaN;
-    OpMap["OP_FMLS_N"] = OpFMlsN;
-    OpMap["OP_MLAL_N"] = OpMlalN;
-    OpMap["OP_MLSL_N"] = OpMlslN;
-    OpMap["OP_MUL_LN"]= OpMulLane;
-    OpMap["OP_MULX_LN"]= OpMulXLane;
-    OpMap["OP_MULL_LN"] = OpMullLane;
-    OpMap["OP_MULLHi_LN"] = OpMullHiLane;
-    OpMap["OP_MLA_LN"]= OpMlaLane;
-    OpMap["OP_MLS_LN"]= OpMlsLane;
-    OpMap["OP_MLAL_LN"] = OpMlalLane;
-    OpMap["OP_MLALHi_LN"] = OpMlalHiLane;
-    OpMap["OP_MLSL_LN"] = OpMlslLane;
-    OpMap["OP_MLSLHi_LN"] = OpMlslHiLane;
-    OpMap["OP_QDMULL_LN"] = OpQDMullLane;
-    OpMap["OP_QDMULLHi_LN"] = OpQDMullHiLane;
-    OpMap["OP_QDMLAL_LN"] = OpQDMlalLane;
-    OpMap["OP_QDMLALHi_LN"] = OpQDMlalHiLane;
-    OpMap["OP_QDMLSL_LN"] = OpQDMlslLane;
-    OpMap["OP_QDMLSLHi_LN"] = OpQDMlslHiLane;
-    OpMap["OP_QDMULH_LN"] = OpQDMulhLane;
-    OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane;
-    OpMap["OP_FMS_LN"] = OpFMSLane;
-    OpMap["OP_FMS_LNQ"] = OpFMSLaneQ;
-    OpMap["OP_TRN1"]  = OpTrn1;
-    OpMap["OP_ZIP1"]  = OpZip1;
-    OpMap["OP_UZP1"]  = OpUzp1;
-    OpMap["OP_TRN2"]  = OpTrn2;
-    OpMap["OP_ZIP2"]  = OpZip2;
-    OpMap["OP_UZP2"]  = OpUzp2;
-    OpMap["OP_EQ"]    = OpEq;
-    OpMap["OP_GE"]    = OpGe;
-    OpMap["OP_LE"]    = OpLe;
-    OpMap["OP_GT"]    = OpGt;
-    OpMap["OP_LT"]    = OpLt;
-    OpMap["OP_NEG"]   = OpNeg;
-    OpMap["OP_NOT"]   = OpNot;
-    OpMap["OP_AND"]   = OpAnd;
-    OpMap["OP_OR"]    = OpOr;
-    OpMap["OP_XOR"]   = OpXor;
-    OpMap["OP_ANDN"]  = OpAndNot;
-    OpMap["OP_ORN"]   = OpOrNot;
-    OpMap["OP_CAST"]  = OpCast;
-    OpMap["OP_CONC"]  = OpConcat;
-    OpMap["OP_HI"]    = OpHi;
-    OpMap["OP_LO"]    = OpLo;
-    OpMap["OP_DUP"]   = OpDup;
-    OpMap["OP_DUP_LN"] = OpDupLane;
-    OpMap["OP_SEL"]   = OpSelect;
-    OpMap["OP_REV16"] = OpRev16;
-    OpMap["OP_REV32"] = OpRev32;
-    OpMap["OP_REV64"] = OpRev64;
-    OpMap["OP_XTN"] = OpXtnHi;
-    OpMap["OP_SQXTUN"] = OpSqxtunHi;
-    OpMap["OP_QXTN"] = OpQxtnHi;
-    OpMap["OP_VCVT_NA_HI"] = OpFcvtnHi;
-    OpMap["OP_VCVT_EX_HI"] = OpFcvtlHi;
-    OpMap["OP_VCVTX_HI"] = OpFcvtxnHi;
-    OpMap["OP_REINT"] = OpReinterpret;
-    OpMap["OP_ADDHNHi"] = OpAddhnHi;
-    OpMap["OP_RADDHNHi"] = OpRAddhnHi;
-    OpMap["OP_SUBHNHi"] = OpSubhnHi;
-    OpMap["OP_RSUBHNHi"] = OpRSubhnHi;
-    OpMap["OP_ABDL"]  = OpAbdl;
-    OpMap["OP_ABDLHi"] = OpAbdlHi;
-    OpMap["OP_ABA"]   = OpAba;
-    OpMap["OP_ABAL"]  = OpAbal;
-    OpMap["OP_ABALHi"] = OpAbalHi;
-    OpMap["OP_QDMULLHi"] = OpQDMullHi;
-    OpMap["OP_QDMULLHi_N"] = OpQDMullHiN;
-    OpMap["OP_QDMLALHi"] = OpQDMlalHi;
-    OpMap["OP_QDMLALHi_N"] = OpQDMlalHiN;
-    OpMap["OP_QDMLSLHi"] = OpQDMlslHi;
-    OpMap["OP_QDMLSLHi_N"] = OpQDMlslHiN;
-    OpMap["OP_DIV"] = OpDiv;
-    OpMap["OP_LONG_HI"] = OpLongHi;
-    OpMap["OP_NARROW_HI"] = OpNarrowHi;
-    OpMap["OP_MOVL_HI"] = OpMovlHi;
-    OpMap["OP_COPY_LN"] = OpCopyLane;
-    OpMap["OP_COPYQ_LN"] = OpCopyQLane;
-    OpMap["OP_COPY_LNQ"] = OpCopyLaneQ;
-    OpMap["OP_SCALAR_MUL_LN"]= OpScalarMulLane;
-    OpMap["OP_SCALAR_MUL_LNQ"]= OpScalarMulLaneQ;
-    OpMap["OP_SCALAR_MULX_LN"]= OpScalarMulXLane;
-    OpMap["OP_SCALAR_MULX_LNQ"]= OpScalarMulXLaneQ;
-    OpMap["OP_SCALAR_VMULX_LN"]= OpScalarVMulXLane;
-    OpMap["OP_SCALAR_VMULX_LNQ"]= OpScalarVMulXLaneQ;
-    OpMap["OP_SCALAR_QDMULL_LN"] = OpScalarQDMullLane;
-    OpMap["OP_SCALAR_QDMULL_LNQ"] = OpScalarQDMullLaneQ;
-    OpMap["OP_SCALAR_QDMULH_LN"] = OpScalarQDMulHiLane;
-    OpMap["OP_SCALAR_QDMULH_LNQ"] = OpScalarQDMulHiLaneQ;
-    OpMap["OP_SCALAR_QRDMULH_LN"] = OpScalarQRDMulHiLane;
-    OpMap["OP_SCALAR_QRDMULH_LNQ"] = OpScalarQRDMulHiLaneQ;
-    OpMap["OP_SCALAR_GET_LN"] = OpScalarGetLane;
-    OpMap["OP_SCALAR_SET_LN"] = OpScalarSetLane;
+  Variable() : T(Type::getVoid()), N("") {}
+  Variable(Type T, std::string N) : T(T), N(N) {}
 
+  Type getType() const { return T; }
+  std::string getName() const { return "__" + N; }
+};
+
+//===----------------------------------------------------------------------===//
+// Intrinsic
+//===----------------------------------------------------------------------===//
+
+/// The main grunt class. This represents an instantiation of an intrinsic with
+/// a particular typespec and prototype.
+class Intrinsic {
+  friend class DagEmitter;
+
+  /// The Record this intrinsic was created from.
+  Record *R;
+  /// The unmangled name and prototype.
+  std::string Name, Proto;
+  /// The input and output typespecs. InTS == OutTS except when
+  /// CartesianProductOfTypes is 1 - this is the case for vreinterpret.
+  TypeSpec OutTS, InTS;
+  /// The base class kind. Most intrinsics use ClassS, which has full type
+  /// info for integers (s32/u32). Some use ClassI, which doesn't care about
+  /// signedness (i32), while some (ClassB) have no type at all, only a width
+  /// (32).
+  ClassKind CK;
+  /// The list of DAGs for the body. May be empty, in which case we should
+  /// emit a builtin call.
+  ListInit *Body;
+  /// The architectural #ifdef guard.
+  std::string Guard;
+  /// Set if the Unvailable bit is 1. This means we don't generate a body,
+  /// just an "unavailable" attribute on a declaration.
+  bool IsUnavailable;
+  /// Is this intrinsic safe for big-endian? or does it need its arguments
+  /// reversing?
+  bool BigEndianSafe;
+
+  /// The types of return value [0] and parameters [1..].
+  std::vector<Type> Types;
+  /// The local variables defined.
+  std::map<std::string, Variable> Variables;
+  /// NeededEarly - set if any other intrinsic depends on this intrinsic.
+  bool NeededEarly;
+  /// UseMacro - set if we should implement using a macro or unset for a
+  ///            function.
+  bool UseMacro;
+  /// The set of intrinsics that this intrinsic uses/requires.
+  std::set<Intrinsic *> Dependencies;
+  /// The "base type", which is Type('d', OutTS). InBaseType is only
+  /// different if CartesianProductOfTypes = 1 (for vreinterpret).
+  Type BaseType, InBaseType;
+  /// The return variable.
+  Variable RetVar;
+  /// A postfix to apply to every variable. Defaults to "".
+  std::string VariablePostfix;
+
+  NeonEmitter &Emitter;
+  std::stringstream OS;
+
+public:
+  Intrinsic(Record *R, StringRef Name, StringRef Proto, TypeSpec OutTS,
+            TypeSpec InTS, ClassKind CK, ListInit *Body, NeonEmitter &Emitter,
+            StringRef Guard, bool IsUnavailable, bool BigEndianSafe)
+      : R(R), Name(Name.str()), Proto(Proto.str()), OutTS(OutTS), InTS(InTS),
+        CK(CK), Body(Body), Guard(Guard.str()), IsUnavailable(IsUnavailable),
+        BigEndianSafe(BigEndianSafe), NeededEarly(false), UseMacro(false),
+        BaseType(OutTS, 'd'), InBaseType(InTS, 'd'), Emitter(Emitter) {
+    // If this builtin takes an immediate argument, we need to #define it rather
+    // than use a standard declaration, so that SemaChecking can range check
+    // the immediate passed by the user.
+    if (Proto.find('i') != std::string::npos)
+      UseMacro = true;
+
+    // Pointer arguments need to use macros to avoid hiding aligned attributes
+    // from the pointer type.
+    if (Proto.find('p') != std::string::npos ||
+        Proto.find('c') != std::string::npos)
+      UseMacro = true;
+
+    // It is not permitted to pass or return an __fp16 by value, so intrinsics
+    // taking a scalar float16_t must be implemented as macros.
+    if (OutTS.find('h') != std::string::npos &&
+        Proto.find('s') != std::string::npos)
+      UseMacro = true;
+
+    // Modify the TypeSpec per-argument to get a concrete Type, and create
+    // known variables for each.
+    // Types[0] is the return value.
+    Types.push_back(Type(OutTS, Proto[0]));
+    for (unsigned I = 1; I < Proto.size(); ++I)
+      Types.push_back(Type(InTS, Proto[I]));
+  }
+
+  /// Get the Record that this intrinsic is based off.
+  Record *getRecord() const { return R; }
+  /// Get the set of Intrinsics that this intrinsic calls.
+  /// this is the set of immediate dependencies, NOT the
+  /// transitive closure.
+  const std::set<Intrinsic *> &getDependencies() const { return Dependencies; }
+  /// Get the architectural guard string (#ifdef).
+  std::string getGuard() const { return Guard; }
+  /// Get the non-mangled name.
+  std::string getName() const { return Name; }
+
+  /// Return true if the intrinsic takes an immediate operand.
+  bool hasImmediate() const {
+    return Proto.find('i') != std::string::npos;
+  }
+  /// Return the parameter index of the immediate operand.
+  unsigned getImmediateIdx() const {
+    assert(hasImmediate());
+    unsigned Idx = Proto.find('i');
+    assert(Idx > 0 && "Can't return an immediate!");
+    return Idx - 1;
+  }
+
+  /// Return true if the intrinsic takes an splat operand.
+  bool hasSplat() const { return Proto.find('a') != std::string::npos; }
+  /// Return the parameter index of the splat operand.
+  unsigned getSplatIdx() const {
+    assert(hasSplat());
+    unsigned Idx = Proto.find('a');
+    assert(Idx > 0 && "Can't return a splat!");
+    return Idx - 1;
+  }
+
+  unsigned getNumParams() const { return Proto.size() - 1; }
+  Type getReturnType() const { return Types[0]; }
+  Type getParamType(unsigned I) const { return Types[I + 1]; }
+  Type getBaseType() const { return BaseType; }
+  /// Return the raw prototype string.
+  std::string getProto() const { return Proto; }
+
+  /// Return true if the prototype has a scalar argument.
+  /// This does not return true for the "splat" code ('a').
+  bool protoHasScalar();
+
+  /// Return the index that parameter PIndex will sit at
+  /// in a generated function call. This is often just PIndex,
+  /// but may not be as things such as multiple-vector operands
+  /// and sret parameters need to be taken into accont.
+  unsigned getGeneratedParamIdx(unsigned PIndex) {
+    unsigned Idx = 0;
+    if (getReturnType().getNumVectors() > 1)
+      // Multiple vectors are passed as sret.
+      ++Idx;
+
+    for (unsigned I = 0; I < PIndex; ++I)
+      Idx += std::max(1U, getParamType(I).getNumVectors());
+
+    return Idx;
+  }
+
+  bool hasBody() const { return Body && Body->getValues().size() > 0; }
+
+  void setNeededEarly() { NeededEarly = true; }
+
+  bool operator<(const Intrinsic &Other) const {
+    // Sort lexicographically on a two-tuple (Guard, Name)
+    if (Guard != Other.Guard)
+      return Guard < Other.Guard;
+    return Name < Other.Name;
+  }
+
+  ClassKind getClassKind(bool UseClassBIfScalar = false) {
+    if (UseClassBIfScalar && !protoHasScalar())
+      return ClassB;
+    return CK;
+  }
+
+  /// Return the name, mangled with type information.
+  /// If ForceClassS is true, use ClassS (u32/s32) instead
+  /// of the intrinsic's own type class.
+  std::string getMangledName(bool ForceClassS = false);
+  /// Return the type code for a builtin function call.
+  std::string getInstTypeCode(Type T, ClassKind CK);
+  /// Return the type string for a BUILTIN() macro in Builtins.def.
+  std::string getBuiltinTypeStr();
+
+  /// Generate the intrinsic, returning code.
+  std::string generate();
+  /// Perform type checking and populate the dependency graph, but
+  /// don't generate code yet.
+  void indexBody();
+
+private:
+  std::string mangleName(std::string Name, ClassKind CK);
+
+  void initVariables();
+  std::string replaceParamsIn(std::string S);
+
+  void emitBodyAsBuiltinCall();
+
+  void generateImpl(bool ReverseArguments,
+                    StringRef NamePrefix, StringRef CallPrefix);
+  void emitReturn();
+  void emitBody(StringRef CallPrefix);
+  void emitShadowedArgs();
+  void emitArgumentReversal();
+  void emitReturnReversal();
+  void emitReverseVariable(Variable &Dest, Variable &Src);
+  void emitNewLine();
+  void emitClosingBrace();
+  void emitOpeningBrace();
+  void emitPrototype(StringRef NamePrefix);
+
+  class DagEmitter {
+    Intrinsic &Intr;
+    StringRef CallPrefix;
+
+  public:
+    DagEmitter(Intrinsic &Intr, StringRef CallPrefix) :
+      Intr(Intr), CallPrefix(CallPrefix) {
+    }
+    std::pair<Type, std::string> emitDagArg(Init *Arg, std::string ArgName);
+    std::pair<Type, std::string> emitDagSaveTemp(DagInit *DI);
+    std::pair<Type, std::string> emitDagSplat(DagInit *DI);
+    std::pair<Type, std::string> emitDagDup(DagInit *DI);
+    std::pair<Type, std::string> emitDagShuffle(DagInit *DI);
+    std::pair<Type, std::string> emitDagCast(DagInit *DI, bool IsBitCast);
+    std::pair<Type, std::string> emitDagCall(DagInit *DI);
+    std::pair<Type, std::string> emitDagNameReplace(DagInit *DI);
+    std::pair<Type, std::string> emitDagLiteral(DagInit *DI);
+    std::pair<Type, std::string> emitDagOp(DagInit *DI);
+    std::pair<Type, std::string> emitDag(DagInit *DI);
+  };
+
+};
+
+//===----------------------------------------------------------------------===//
+// NeonEmitter
+//===----------------------------------------------------------------------===//
+
+class NeonEmitter {
+  RecordKeeper &Records;
+  DenseMap<Record *, ClassKind> ClassMap;
+  std::map<std::string, std::vector<Intrinsic *>> IntrinsicMap;
+  unsigned UniqueNumber;
+
+  void createIntrinsic(Record *R, SmallVectorImpl<Intrinsic *> &Out);
+  void genBuiltinsDef(raw_ostream &OS, SmallVectorImpl<Intrinsic *> &Defs);
+  void genOverloadTypeCheckCode(raw_ostream &OS,
+                                SmallVectorImpl<Intrinsic *> &Defs);
+  void genIntrinsicRangeCheckCode(raw_ostream &OS,
+                                  SmallVectorImpl<Intrinsic *> &Defs);
+
+public:
+  /// Called by Intrinsic - this attempts to get an intrinsic that takes
+  /// the given types as arguments.
+  Intrinsic *getIntrinsic(StringRef Name, ArrayRef<Type> Types);
+
+  /// Called by Intrinsic - returns a globally-unique number.
+  unsigned getUniqueNumber() { return UniqueNumber++; }
+
+  NeonEmitter(RecordKeeper &R) : Records(R), UniqueNumber(0) {
     Record *SI = R.getClass("SInst");
     Record *II = R.getClass("IInst");
     Record *WI = R.getClass("WInst");
@@ -370,2258 +530,1702 @@
 
   // runTests - Emit tests for all the Neon intrinsics.
   void runTests(raw_ostream &o);
-
-private:
-  void emitGuardedIntrinsic(raw_ostream &OS, Record *R,
-                            std::string &CurrentGuard, bool &InGuard,
-                            StringMap<ClassKind> &EmittedMap);
-  void emitIntrinsic(raw_ostream &OS, Record *R,
-                     StringMap<ClassKind> &EmittedMap);
-  void genBuiltinsDef(raw_ostream &OS);
-  void genOverloadTypeCheckCode(raw_ostream &OS);
-  void genIntrinsicRangeCheckCode(raw_ostream &OS);
-  void genTargetTest(raw_ostream &OS);
 };
+
 } // end anonymous namespace
 
-/// ParseTypes - break down a string such as "fQf" into a vector of StringRefs,
-/// which each StringRef representing a single type declared in the string.
-/// for "fQf" we would end up with 2 StringRefs, "f", and "Qf", representing
-/// 2xfloat and 4xfloat respectively.
-static void ParseTypes(Record *r, std::string &s,
-                       SmallVectorImpl<StringRef> &TV) {
-  const char *data = s.data();
-  int len = 0;
+//===----------------------------------------------------------------------===//
+// Type implementation
+//===----------------------------------------------------------------------===//
 
-  for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) {
-    if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U'
-                         || data[len] == 'H' || data[len] == 'S')
-      continue;
-
-    switch (data[len]) {
-      case 'c':
-      case 's':
-      case 'i':
-      case 'l':
-      case 'k':
-      case 'h':
-      case 'f':
-      case 'd':
-        break;
-      default:
-        PrintFatalError(r->getLoc(),
-                      "Unexpected letter: " + std::string(data + len, 1));
-    }
-    TV.push_back(StringRef(data, len + 1));
-    data += len + 1;
-    len = -1;
-  }
-}
-
-/// Widen - Convert a type code into the next wider type.  char -> short,
-/// short -> int, etc.
-static char Widen(const char t) {
-  switch (t) {
-    case 'c':
-      return 's';
-    case 's':
-      return 'i';
-    case 'i':
-      return 'l';
-    case 'l':
-      return 'k';
-    case 'h':
-      return 'f';
-    case 'f':
-      return 'd';
-    default:
-      PrintFatalError("unhandled type in widen!");
-  }
-}
-
-/// Narrow - Convert a type code into the next smaller type.  short -> char,
-/// float -> half float, etc.
-static char Narrow(const char t) {
-  switch (t) {
-    case 's':
-      return 'c';
-    case 'i':
-      return 's';
-    case 'l':
-      return 'i';
-    case 'k':
-      return 'l';
-    case 'f':
-      return 'h';
-    case 'd':
-      return 'f';
-    default:
-      PrintFatalError("unhandled type in narrow!");
-  }
-}
-
-static std::string GetNarrowTypestr(StringRef ty)
-{
-  std::string s;
-  for (size_t i = 0, end = ty.size(); i < end; i++) {
-    switch (ty[i]) {
-      case 's':
-        s += 'c';
-        break;
-      case 'i':
-        s += 's';
-        break;
-      case 'l':
-        s += 'i';
-        break;
-      case 'k':
-        s += 'l';
-        break;
-      default:
-        s += ty[i];
-        break;
-    }
-  }
-
-  return s;
-}
-
-/// For a particular StringRef, return the base type code, and whether it has
-/// the quad-vector, polynomial, or unsigned modifiers set.
-static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) {
-  unsigned off = 0;
-  // ignore scalar.
-  if (ty[off] == 'S') {
-    ++off;
-  }
-  // remember quad.
-  if (ty[off] == 'Q' || ty[off] == 'H') {
-    quad = true;
-    ++off;
-  }
-
-  // remember poly.
-  if (ty[off] == 'P') {
-    poly = true;
-    ++off;
-  }
-
-  // remember unsigned.
-  if (ty[off] == 'U') {
-    usgn = true;
-    ++off;
-  }
-
-  // base type to get the type string for.
-  return ty[off];
-}
-
-/// ModType - Transform a type code and its modifiers based on a mod code. The
-/// mod code definitions may be found at the top of arm_neon.td.
-static char ModType(const char mod, char type, bool &quad, bool &poly,
-                    bool &usgn, bool &scal, bool &cnst, bool &pntr) {
-  switch (mod) {
-    case 't':
-      if (poly) {
-        poly = false;
-        usgn = true;
-      }
-      break;
-    case 'b':
-      scal = true;
-    case 'u':
-      usgn = true;
-      poly = false;
-      if (type == 'f')
-        type = 'i';
-      if (type == 'd')
-        type = 'l';
-      break;
-    case '$':
-      scal = true;
-    case 'x':
-      usgn = false;
-      poly = false;
-      if (type == 'f')
-        type = 'i';
-      if (type == 'd')
-        type = 'l';
-      break;
-    case 'o':
-      scal = true;
-      type = 'd';
-      usgn = false;
-      break;
-    case 'y':
-      scal = true;
-    case 'f':
-      if (type == 'h')
-        quad = true;
-      type = 'f';
-      usgn = false;
-      break;
-    case 'F':
-      type = 'd';
-      usgn = false;
-      break;
-    case 'g':
-      quad = false;
-      break;
-    case 'B':
-    case 'C':
-    case 'D':
-    case 'j':
-      quad = true;
-      break;
-    case 'w':
-      type = Widen(type);
-      quad = true;
-      break;
-    case 'n':
-      type = Widen(type);
-      break;
-    case 'i':
-      type = 'i';
-      scal = true;
-      break;
-    case 'l':
-      type = 'l';
-      scal = true;
-      usgn = true;
-      break;
-    case 'z':
-      type = Narrow(type);
-      scal = true;
-      break;
-    case 'r':
-      type = Widen(type);
-      scal = true;
-      break;
-    case 's':
-    case 'a':
-      scal = true;
-      break;
-    case 'k':
-      quad = true;
-      break;
-    case 'c':
-      cnst = true;
-    case 'p':
-      pntr = true;
-      scal = true;
-      break;
-    case 'h':
-      type = Narrow(type);
-      if (type == 'h')
-        quad = false;
-      break;
-    case 'q':
-      type = Narrow(type);
-      quad = true;
-      break;
-    case 'e':
-      type = Narrow(type);
-      usgn = true;
-      break;
-    case 'm':
-      type = Narrow(type);
-      quad = false;
-      break;
-    default:
-      break;
-  }
-  return type;
-}
-
-static bool IsMultiVecProto(const char p) {
-  return ((p >= '2' && p <= '4') || (p >= 'B' && p <= 'D'));
-}
-
-/// TypeString - for a modifier and type, generate the name of the typedef for
-/// that type.  QUc -> uint8x8_t.
-static std::string TypeString(const char mod, StringRef typestr) {
-  bool quad = false;
-  bool poly = false;
-  bool usgn = false;
-  bool scal = false;
-  bool cnst = false;
-  bool pntr = false;
-
-  if (mod == 'v')
+std::string Type::str() const {
+  if (Void)
     return "void";
-  if (mod == 'i')
-    return "int";
+  std::string S;
 
-  // base type to get the type string for.
-  char type = ClassifyType(typestr, quad, poly, usgn);
+  if (!Signed && isInteger())
+    S += "u";
 
-  // Based on the modifying character, change the type and width if necessary.
-  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
+  if (Poly)
+    S += "poly";
+  else if (Float)
+    S += "float";
+  else
+    S += "int";
 
-  SmallString<128> s;
+  S += utostr(ElementBitwidth);
+  if (isVector())
+    S += "x" + utostr(getNumElements());
+  if (NumVectors > 1)
+    S += "x" + utostr(NumVectors);
+  S += "_t";
 
-  if (usgn)
-    s.push_back('u');
+  if (Constant)
+    S += " const";
+  if (Pointer)
+    S += " *";
 
-  switch (type) {
-    case 'c':
-      s += poly ? "poly8" : "int8";
-      if (scal)
-        break;
-      s += quad ? "x16" : "x8";
-      break;
-    case 's':
-      s += poly ? "poly16" : "int16";
-      if (scal)
-        break;
-      s += quad ? "x8" : "x4";
-      break;
-    case 'i':
-      s += "int32";
-      if (scal)
-        break;
-      s += quad ? "x4" : "x2";
-      break;
-    case 'l':
-      s += (poly && !usgn)? "poly64" : "int64";
-      if (scal)
-        break;
-      s += quad ? "x2" : "x1";
-      break;
-    case 'k':
-      s += "poly128";
-      break;
-    case 'h':
-      s += "float16";
-      if (scal)
-        break;
-      s += quad ? "x8" : "x4";
-      break;
-    case 'f':
-      s += "float32";
-      if (scal)
-        break;
-      s += quad ? "x4" : "x2";
-      break;
-    case 'd':
-      s += "float64";
-      if (scal)
-        break;
-      s += quad ? "x2" : "x1";
-      break;
-
-    default:
-      PrintFatalError("unhandled type!");
-  }
-
-  if (mod == '2' || mod == 'B')
-    s += "x2";
-  if (mod == '3' || mod == 'C')
-    s += "x3";
-  if (mod == '4' || mod == 'D')
-    s += "x4";
-
-  // Append _t, finishing the type string typedef type.
-  s += "_t";
-
-  if (cnst)
-    s += " const";
-
-  if (pntr)
-    s += " *";
-
-  return s.str();
+  return S;
 }
 
-/// BuiltinTypeString - for a modifier and type, generate the clang
-/// BuiltinsARM.def prototype code for the function.  See the top of clang's
-/// Builtins.def for a description of the type strings.
-static std::string BuiltinTypeString(const char mod, StringRef typestr,
-                                     ClassKind ck, bool ret) {
-  bool quad = false;
-  bool poly = false;
-  bool usgn = false;
-  bool scal = false;
-  bool cnst = false;
-  bool pntr = false;
+std::string Type::builtin_str() const {
+  std::string S;
+  if (isVoid())
+    return "v";
 
-  if (mod == 'v')
-    return "v"; // void
-  if (mod == 'i')
-    return "i"; // int
+  if (Pointer)
+    // All pointers are void pointers.
+    S += "v";
+  else if (isInteger())
+    switch (ElementBitwidth) {
+    case 8: S += "c"; break;
+    case 16: S += "s"; break;
+    case 32: S += "i"; break;
+    case 64: S += "Wi"; break;
+    case 128: S += "LLLi"; break;
+    default: llvm_unreachable("Unhandled case!");
+    }
+  else
+    switch (ElementBitwidth) {
+    case 16: S += "h"; break;
+    case 32: S += "f"; break;
+    case 64: S += "d"; break;
+    default: llvm_unreachable("Unhandled case!");
+    }
 
-  // base type to get the type string for.
-  char type = ClassifyType(typestr, quad, poly, usgn);
+  if (isChar() && !Pointer)
+    // Make chars explicitly signed.
+    S = "S" + S;
+  else if (isInteger() && !Pointer && !Signed)
+    S = "U" + S;
 
-  // Based on the modifying character, change the type and width if necessary.
-  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
-
-  usgn = usgn | poly | ((ck == ClassI || ck == ClassW) &&
-                         scal && type != 'f' && type != 'd');
-
-  // All pointers are void* pointers.  Change type to 'v' now.
-  if (pntr) {
-    usgn = false;
-    poly = false;
-    type = 'v';
-  }
-  // Treat half-float ('h') types as unsigned short ('s') types.
-  if (type == 'h') {
-    type = 's';
-    usgn = true;
+  if (isScalar()) {
+    if (Constant) S += "C";
+    if (Pointer) S += "*";
+    return S;
   }
 
-  if (scal) {
-    SmallString<128> s;
+  std::string Ret;
+  for (unsigned I = 0; I < NumVectors; ++I)
+    Ret += "V" + utostr(getNumElements()) + S;
 
-    if (usgn)
-      s.push_back('U');
-    else if (type == 'c')
-      s.push_back('S'); // make chars explicitly signed
+  return Ret;
+}
 
-    if (type == 'l') // 64-bit long
-      s += "Wi";
-    else if (type == 'k') // 128-bit long
-      s = "LLLi";
-    else
-      s.push_back(type);
-
-    if (cnst)
-      s.push_back('C');
-    if (pntr)
-      s.push_back('*');
-    return s.str();
+unsigned Type::getNeonEnum() const {
+  unsigned Addend;
+  switch (ElementBitwidth) {
+  case 8: Addend = 0; break;
+  case 16: Addend = 1; break;
+  case 32: Addend = 2; break;
+  case 64: Addend = 3; break;
+  case 128: Addend = 4; break;
+  default: llvm_unreachable("Unhandled element bitwidth!");
   }
 
+  unsigned Base = (unsigned)NeonTypeFlags::Int8 + Addend;
+  if (Poly) {
+    // Adjustment needed because Poly32 doesn't exist.
+    if (Addend >= 2)
+      --Addend;
+    Base = (unsigned)NeonTypeFlags::Poly8 + Addend;
+  }
+  if (Float) {
+    assert(Addend != 0 && "Float8 doesn't exist!");
+    Base = (unsigned)NeonTypeFlags::Float16 + (Addend - 1);
+  }
+
+  if (Bitwidth == 128)
+    Base |= (unsigned)NeonTypeFlags::QuadFlag;
+  if (isInteger() && !Signed)
+    Base |= (unsigned)NeonTypeFlags::UnsignedFlag;
+
+  return Base;
+}
+
+Type Type::fromTypedefName(StringRef Name) {
+  Type T;
+  T.Void = false;
+  T.Float = false;
+  T.Poly = false;
+
+  if (Name.front() == 'u') {
+    T.Signed = false;
+    Name = Name.drop_front();
+  } else {
+    T.Signed = true;
+  }
+
+  if (Name.startswith("float")) {
+    T.Float = true;
+    Name = Name.drop_front(5);
+  } else if (Name.startswith("poly")) {
+    T.Poly = true;
+    Name = Name.drop_front(4);
+  } else {
+    assert(Name.startswith("int"));
+    Name = Name.drop_front(3);
+  }
+
+  unsigned I = 0;
+  for (I = 0; I < Name.size(); ++I) {
+    if (!isdigit(Name[I]))
+      break;
+  }
+  Name.substr(0, I).getAsInteger(10, T.ElementBitwidth);
+  Name = Name.drop_front(I);
+
+  T.Bitwidth = T.ElementBitwidth;
+  T.NumVectors = 1;
+
+  if (Name.front() == 'x') {
+    Name = Name.drop_front();
+    unsigned I = 0;
+    for (I = 0; I < Name.size(); ++I) {
+      if (!isdigit(Name[I]))
+        break;
+    }
+    unsigned NumLanes;
+    Name.substr(0, I).getAsInteger(10, NumLanes);
+    Name = Name.drop_front(I);
+    T.Bitwidth = T.ElementBitwidth * NumLanes;
+  } else {
+    // Was scalar.
+    T.NumVectors = 0;
+  }
+  if (Name.front() == 'x') {
+    Name = Name.drop_front();
+    unsigned I = 0;
+    for (I = 0; I < Name.size(); ++I) {
+      if (!isdigit(Name[I]))
+        break;
+    }
+    Name.substr(0, I).getAsInteger(10, T.NumVectors);
+    Name = Name.drop_front(I);
+  }
+
+  assert(Name.startswith("_t") && "Malformed typedef!");
+  return T;
+}
+
+void Type::applyTypespec(bool &Quad) {
+  std::string S = TS;
+  ScalarForMangling = false;
+  Void = false;
+  Poly = Float = false;
+  ElementBitwidth = ~0U;
+  Signed = true;
+  NumVectors = 1;
+
+  for (char I : S) {
+    switch (I) {
+    case 'S':
+      ScalarForMangling = true;
+      break;
+    case 'H':
+      NoManglingQ = true;
+      Quad = true;
+      break;
+    case 'Q':
+      Quad = true;
+      break;
+    case 'P':
+      Poly = true;
+      break;
+    case 'U':
+      Signed = false;
+      break;
+    case 'c':
+      ElementBitwidth = 8;
+      break;
+    case 'h':
+      Float = true;
+    // Fall through
+    case 's':
+      ElementBitwidth = 16;
+      break;
+    case 'f':
+      Float = true;
+    // Fall through
+    case 'i':
+      ElementBitwidth = 32;
+      break;
+    case 'd':
+      Float = true;
+    // Fall through
+    case 'l':
+      ElementBitwidth = 64;
+      break;
+    case 'k':
+      ElementBitwidth = 128;
+      // Poly doesn't have a 128x1 type.
+      if (Poly)
+        NumVectors = 0;
+      break;
+    default:
+      llvm_unreachable("Unhandled type code!");
+    }
+  }
+  assert(ElementBitwidth != ~0U && "Bad element bitwidth!");
+
+  Bitwidth = Quad ? 128 : 64;
+}
+
+void Type::applyModifier(char Mod) {
+  bool AppliedQuad = false;
+  applyTypespec(AppliedQuad);
+
+  switch (Mod) {
+  case 'v':
+    Void = true;
+    break;
+  case 't':
+    if (Poly) {
+      Poly = false;
+      Signed = false;
+    }
+    break;
+  case 'b':
+    Signed = false;
+    Float = false;
+    Poly = false;
+    NumVectors = 0;
+    Bitwidth = ElementBitwidth;
+    break;
+  case '$':
+    Signed = true;
+    Float = false;
+    Poly = false;
+    NumVectors = 0;
+    Bitwidth = ElementBitwidth;
+    break;
+  case 'u':
+    Signed = false;
+    Poly = false;
+    Float = false;
+    break;
+  case 'x':
+    Signed = true;
+    assert(!Poly && "'u' can't be used with poly types!");
+    Float = false;
+    break;
+  case 'o':
+    Bitwidth = ElementBitwidth = 64;
+    NumVectors = 0;
+    Float = true;
+    break;
+  case 'y':
+    Bitwidth = ElementBitwidth = 32;
+    NumVectors = 0;
+    Float = true;
+    break;
+  case 'f':
+    // Special case - if we're half-precision, a floating
+    // point argument needs to be 128-bits (double size).
+    if (isHalf())
+      Bitwidth = 128;
+    Float = true;
+    ElementBitwidth = 32;
+    break;
+  case 'F':
+    Float = true;
+    ElementBitwidth = 64;
+    break;
+  case 'g':
+    if (AppliedQuad)
+      Bitwidth /= 2;
+    break;
+  case 'j':
+    if (!AppliedQuad)
+      Bitwidth *= 2;
+    break;
+  case 'w':
+    ElementBitwidth *= 2;
+    Bitwidth *= 2;
+    break;
+  case 'n':
+    ElementBitwidth *= 2;
+    break;
+  case 'i':
+    Float = false;
+    Poly = false;
+    ElementBitwidth = Bitwidth = 32;
+    NumVectors = 0;
+    Signed = true;
+    break;
+  case 'l':
+    Float = false;
+    Poly = false;
+    ElementBitwidth = Bitwidth = 64;
+    NumVectors = 0;
+    Signed = false;
+    break;
+  case 'z':
+    ElementBitwidth /= 2;
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+    break;
+  case 'r':
+    ElementBitwidth *= 2;
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+    break;
+  case 's':
+  case 'a':
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+    break;
+  case 'k':
+    Bitwidth *= 2;
+    break;
+  case 'c':
+    Constant = true;
+  // Fall through
+  case 'p':
+    Pointer = true;
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+    break;
+  case 'h':
+    ElementBitwidth /= 2;
+    break;
+  case 'q':
+    ElementBitwidth /= 2;
+    Bitwidth *= 2;
+    break;
+  case 'e':
+    ElementBitwidth /= 2;
+    Signed = false;
+    break;
+  case 'm':
+    ElementBitwidth /= 2;
+    Bitwidth /= 2;
+    break;
+  case 'd':
+    break;
+  case '2':
+    NumVectors = 2;
+    break;
+  case '3':
+    NumVectors = 3;
+    break;
+  case '4':
+    NumVectors = 4;
+    break;
+  case 'B':
+    NumVectors = 2;
+    if (!AppliedQuad)
+      Bitwidth *= 2;
+    break;
+  case 'C':
+    NumVectors = 3;
+    if (!AppliedQuad)
+      Bitwidth *= 2;
+    break;
+  case 'D':
+    NumVectors = 4;
+    if (!AppliedQuad)
+      Bitwidth *= 2;
+    break;
+  default:
+    llvm_unreachable("Unhandled character!");
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Intrinsic implementation
+//===----------------------------------------------------------------------===//
+
+std::string Intrinsic::getInstTypeCode(Type T, ClassKind CK) {
+  char typeCode = '\0';
+  bool printNumber = true;
+
+  if (CK == ClassB)
+    return "";
+
+  if (T.isPoly())
+    typeCode = 'p';
+  else if (T.isInteger())
+    typeCode = T.isSigned() ? 's' : 'u';
+  else
+    typeCode = 'f';
+
+  if (CK == ClassI) {
+    switch (typeCode) {
+    default:
+      break;
+    case 's':
+    case 'u':
+    case 'p':
+      typeCode = 'i';
+      break;
+    }
+  }
+  if (CK == ClassB) {
+    typeCode = '\0';
+  }
+
+  std::string S;
+  if (typeCode != '\0')
+    S.push_back(typeCode);
+  if (printNumber)
+    S += utostr(T.getElementSizeInBits());
+
+  return S;
+}
+
+std::string Intrinsic::getBuiltinTypeStr() {
+  ClassKind LocalCK = getClassKind(true);
+  std::string S;
+
+  Type RetT = getReturnType();
+  if ((LocalCK == ClassI || LocalCK == ClassW) && RetT.isScalar() &&
+      !RetT.isFloating())
+    RetT.makeInteger(RetT.getElementSizeInBits(), false);
+
   // Since the return value must be one type, return a vector type of the
   // appropriate width which we will bitcast.  An exception is made for
   // returning structs of 2, 3, or 4 vectors which are returned in a sret-like
   // fashion, storing them to a pointer arg.
-  if (ret) {
-    if (IsMultiVecProto(mod))
-      return "vv*"; // void result with void* first argument
-    if (mod == 'f' || (ck != ClassB && type == 'f'))
-      return quad ? "V4f" : "V2f";
-    if (mod == 'F' || (ck != ClassB && type == 'd'))
-      return quad ? "V2d" : "V1d";
-    if (ck != ClassB && type == 's')
-      return quad ? "V8s" : "V4s";
-    if (ck != ClassB && type == 'i')
-      return quad ? "V4i" : "V2i";
-    if (ck != ClassB && type == 'l')
-      return quad ? "V2Wi" : "V1Wi";
+  if (RetT.getNumVectors() > 1) {
+    S += "vv*"; // void result with void* first argument
+  } else {
+    if (RetT.isPoly())
+      RetT.makeInteger(RetT.getElementSizeInBits(), false);
+    if (!RetT.isScalar() && !RetT.isSigned())
+      RetT.makeSigned();
 
-    return quad ? "V16Sc" : "V8Sc";
+    bool ForcedVectorFloatingType = Proto[0] == 'F' || Proto[0] == 'f';
+    if (LocalCK == ClassB && !RetT.isScalar() && !ForcedVectorFloatingType)
+      // Cast to vector of 8-bit elements.
+      RetT.makeInteger(8, true);
+
+    S += RetT.builtin_str();
   }
 
-  // Non-return array types are passed as individual vectors.
-  if (mod == '2' || mod == 'B')
-    return quad ? "V16ScV16Sc" : "V8ScV8Sc";
-  if (mod == '3' || mod == 'C')
-    return quad ? "V16ScV16ScV16Sc" : "V8ScV8ScV8Sc";
-  if (mod == '4' || mod == 'D')
-    return quad ? "V16ScV16ScV16ScV16Sc" : "V8ScV8ScV8ScV8Sc";
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    Type T = getParamType(I);
+    if (T.isPoly())
+      T.makeInteger(T.getElementSizeInBits(), false);
 
-  if (mod == 'f' || (ck != ClassB && type == 'f'))
-    return quad ? "V4f" : "V2f";
-  if (mod == 'F' || (ck != ClassB && type == 'd'))
-    return quad ? "V2d" : "V1d";
-  if (ck != ClassB && type == 's')
-    return quad ? "V8s" : "V4s";
-  if (ck != ClassB && type == 'i')
-    return quad ? "V4i" : "V2i";
-  if (ck != ClassB && type == 'l')
-    return quad ? "V2Wi" : "V1Wi";
+    bool ForcedFloatingType = Proto[I + 1] == 'F' || Proto[I + 1] == 'f';
+    if (LocalCK == ClassB && !T.isScalar() && !ForcedFloatingType)
+      T.makeInteger(8, true);
+    // Halves always get converted to 8-bit elements.
+    if (T.isHalf() && T.isVector() && !T.isScalarForMangling())
+      T.makeInteger(8, true);
 
-  return quad ? "V16Sc" : "V8Sc";
-}
+    if (LocalCK == ClassI)
+      T.makeSigned();
 
-/// InstructionTypeCode - Computes the ARM argument character code and
-/// quad status for a specific type string and ClassKind.
-static void InstructionTypeCode(const StringRef &typeStr,
-                                const ClassKind ck,
-                                bool &quad,
-                                std::string &typeCode) {
-  bool poly = false;
-  bool usgn = false;
-  char type = ClassifyType(typeStr, quad, poly, usgn);
+    // Constant indices are always just "int".
+    if (hasImmediate() && getImmediateIdx() == I)
+      T.makeInteger(32, true);
 
-  switch (type) {
-  case 'c':
-    switch (ck) {
-    case ClassS: typeCode = poly ? "p8" : usgn ? "u8" : "s8"; break;
-    case ClassI: typeCode = "i8"; break;
-    case ClassW: typeCode = "8"; break;
-    default: break;
-    }
-    break;
-  case 's':
-    switch (ck) {
-    case ClassS: typeCode = poly ? "p16" : usgn ? "u16" : "s16"; break;
-    case ClassI: typeCode = "i16"; break;
-    case ClassW: typeCode = "16"; break;
-    default: break;
-    }
-    break;
-  case 'i':
-    switch (ck) {
-    case ClassS: typeCode = usgn ? "u32" : "s32"; break;
-    case ClassI: typeCode = "i32"; break;
-    case ClassW: typeCode = "32"; break;
-    default: break;
-    }
-    break;
-  case 'l':
-    switch (ck) {
-    case ClassS: typeCode = poly ? "p64" : usgn ? "u64" : "s64"; break;
-    case ClassI: typeCode = "i64"; break;
-    case ClassW: typeCode = "64"; break;
-    default: break;
-    }
-    break;
-  case 'k':
-    assert(poly && "Unrecognized 128 bit integer.");
-    typeCode = "p128";
-    break;
-  case 'h':
-    switch (ck) {
-    case ClassS:
-    case ClassI: typeCode = "f16"; break;
-    case ClassW: typeCode = "16"; break;
-    default: break;
-    }
-    break;
-  case 'f':
-    switch (ck) {
-    case ClassS:
-    case ClassI: typeCode = "f32"; break;
-    case ClassW: typeCode = "32"; break;
-    default: break;
-    }
-    break;
-  case 'd':
-    switch (ck) {
-    case ClassS:
-    case ClassI:
-      typeCode += "f64";
-      break;
-    case ClassW:
-      PrintFatalError("unhandled type!");
-    default:
-      break;
-    }
-    break;
-  default:
-    PrintFatalError("unhandled type!");
+    S += T.builtin_str();
   }
+
+  // Extra constant integer to hold type class enum for this function, e.g. s8
+  if (LocalCK == ClassB)
+    S += "i";
+
+  return S;
 }
 
-static char Insert_BHSD_Suffix(StringRef typestr){
-  unsigned off = 0;
-  if(typestr[off++] == 'S'){
-    while(typestr[off] == 'Q' || typestr[off] == 'H'||
-          typestr[off] == 'P' || typestr[off] == 'U')
-      ++off;
-    switch (typestr[off]){
-    default  : break;
-    case 'c' : return 'b';
-    case 's' : return 'h';
-    case 'i' :
-    case 'f' : return 's';
-    case 'l' :
-    case 'd' : return 'd';
-    }
-  }
-  return 0;
+std::string Intrinsic::getMangledName(bool ForceClassS) {
+  // Check if the prototype has a scalar operand with the type of the vector
+  // elements.  If not, bitcasting the args will take care of arg checking.
+  // The actual signedness etc. will be taken care of with special enums.
+  ClassKind LocalCK = CK;
+  if (!protoHasScalar())
+    LocalCK = ClassB;
+
+  return mangleName(Name, ForceClassS ? ClassS : LocalCK);
 }
 
-static bool endsWith_xN(std::string const &name) {
-  if (name.length() > 3) {
-    if (name.compare(name.length() - 3, 3, "_x2") == 0 ||
-        name.compare(name.length() - 3, 3, "_x3") == 0 ||
-        name.compare(name.length() - 3, 3, "_x4") == 0)
-      return true;
-  }
-  return false;
-}
+std::string Intrinsic::mangleName(std::string Name, ClassKind LocalCK) {
+  std::string typeCode = getInstTypeCode(BaseType, LocalCK);
+  std::string S = Name;
 
-/// MangleName - Append a type or width suffix to a base neon function name,
-/// and insert a 'q' in the appropriate location if type string starts with 'Q'.
-/// E.g. turn "vst2_lane" into "vst2q_lane_f32", etc.
-/// Insert proper 'b' 'h' 's' 'd' if prefix 'S' is used.
-static std::string MangleName(const std::string &name, StringRef typestr,
-                              ClassKind ck) {
-  if (name == "vcvt_f32_f16" || name == "vcvt_f32_f64" ||
-      name == "vcvt_f64_f32")
-    return name;
-
-  bool quad = false;
-  std::string typeCode = "";
-
-  InstructionTypeCode(typestr, ck, quad, typeCode);
-
-  std::string s = name;
+  if (Name == "vcvt_f32_f16" || Name == "vcvt_f32_f64" ||
+      Name == "vcvt_f64_f32")
+    return Name;
 
   if (typeCode.size() > 0) {
-    // If the name is end with _xN (N = 2,3,4), insert the typeCode before _xN.
-    if (endsWith_xN(s))
-      s.insert(s.length() - 3, "_" + typeCode);
+    // If the name ends with _xN (N = 2,3,4), insert the typeCode before _xN.
+    if (Name.size() >= 3 && isdigit(Name.back()) &&
+        Name[Name.length() - 2] == 'x' && Name[Name.length() - 3] == '_')
+      S.insert(S.length() - 3, "_" + typeCode);
     else
-      s += "_" + typeCode;
+      S += "_" + typeCode;
   }
 
-  if (ck == ClassB)
-    s += "_v";
+  if (BaseType != InBaseType) {
+    // A reinterpret - out the input base type at the end.
+    S += "_" + getInstTypeCode(InBaseType, LocalCK);
+  }
+
+  if (LocalCK == ClassB)
+    S += "_v";
 
   // Insert a 'q' before the first '_' character so that it ends up before
   // _lane or _n on vector-scalar operations.
-  if (typestr.find("Q") != StringRef::npos) {
-      size_t pos = s.find('_');
-      s = s.insert(pos, "q");
-  }
-  char ins = Insert_BHSD_Suffix(typestr);
-  if(ins){
-    size_t pos = s.find('_');
-    s = s.insert(pos, &ins, 1);
+  if (BaseType.getSizeInBits() == 128 && !BaseType.noManglingQ()) {
+    size_t Pos = S.find('_');
+    S.insert(Pos, "q");
   }
 
-  return s;
-}
-
-static void PreprocessInstruction(const StringRef &Name,
-                                  const std::string &InstName,
-                                  std::string &Prefix,
-                                  bool &HasNPostfix,
-                                  bool &HasLanePostfix,
-                                  bool &HasDupPostfix,
-                                  bool &IsSpecialVCvt,
-                                  size_t &TBNumber) {
-  // All of our instruction name fields from arm_neon.td are of the form
-  //   <instructionname>_...
-  // Thus we grab our instruction name via computation of said Prefix.
-  const size_t PrefixEnd = Name.find_first_of('_');
-  // If InstName is passed in, we use that instead of our name Prefix.
-  Prefix = InstName.size() == 0? Name.slice(0, PrefixEnd).str() : InstName;
-
-  const StringRef Postfix = Name.slice(PrefixEnd, Name.size());
-
-  HasNPostfix = Postfix.count("_n");
-  HasLanePostfix = Postfix.count("_lane");
-  HasDupPostfix = Postfix.count("_dup");
-  IsSpecialVCvt = Postfix.size() != 0 && Name.count("vcvt");
-
-  if (InstName.compare("vtbl") == 0 ||
-      InstName.compare("vtbx") == 0) {
-    // If we have a vtblN/vtbxN instruction, use the instruction's ASCII
-    // encoding to get its true value.
-    TBNumber = Name[Name.size()-1] - 48;
-  }
-}
-
-/// GenerateRegisterCheckPatternsForLoadStores - Given a bunch of data we have
-/// extracted, generate a FileCheck pattern for a Load Or Store
-static void
-GenerateRegisterCheckPatternForLoadStores(const StringRef &NameRef,
-                                          const std::string& OutTypeCode,
-                                          const bool &IsQuad,
-                                          const bool &HasDupPostfix,
-                                          const bool &HasLanePostfix,
-                                          const size_t Count,
-                                          std::string &RegisterSuffix) {
-  const bool IsLDSTOne = NameRef.count("vld1") || NameRef.count("vst1");
-  // If N == 3 || N == 4 and we are dealing with a quad instruction, Clang
-  // will output a series of v{ld,st}1s, so we have to handle it specially.
-  if ((Count == 3 || Count == 4) && IsQuad) {
-    RegisterSuffix += "{";
-    for (size_t i = 0; i < Count; i++) {
-      RegisterSuffix += "d{{[0-9]+}}";
-      if (HasDupPostfix) {
-        RegisterSuffix += "[]";
-      }
-      if (HasLanePostfix) {
-        RegisterSuffix += "[{{[0-9]+}}]";
-      }
-      if (i < Count-1) {
-        RegisterSuffix += ", ";
-      }
+  char Suffix = '\0';
+  if (BaseType.isScalarForMangling()) {
+    switch (BaseType.getElementSizeInBits()) {
+    case 8: Suffix = 'b'; break;
+    case 16: Suffix = 'h'; break;
+    case 32: Suffix = 's'; break;
+    case 64: Suffix = 'd'; break;
+    default: llvm_unreachable("Bad suffix!");
     }
-    RegisterSuffix += "}";
+  }
+  if (Suffix != '\0') {
+    size_t Pos = S.find('_');
+    S.insert(Pos, &Suffix, 1);
+  }
+
+  return S;
+}
+
+std::string Intrinsic::replaceParamsIn(std::string S) {
+  while (S.find('$') != std::string::npos) {
+    size_t Pos = S.find('$');
+    size_t End = Pos + 1;
+    while (isalpha(S[End]))
+      ++End;
+
+    std::string VarName = S.substr(Pos + 1, End - Pos - 1);
+    assert_with_loc(Variables.find(VarName) != Variables.end(),
+                    "Variable not defined!");
+    S.replace(Pos, End - Pos, Variables.find(VarName)->second.getName());
+  }
+
+  return S;
+}
+
+void Intrinsic::initVariables() {
+  Variables.clear();
+
+  // Modify the TypeSpec per-argument to get a concrete Type, and create
+  // known variables for each.
+  for (unsigned I = 1; I < Proto.size(); ++I) {
+    char NameC = '0' + (I - 1);
+    std::string Name = "p";
+    Name.push_back(NameC);
+
+    Variables[Name] = Variable(Types[I], Name + VariablePostfix);
+  }
+  RetVar = Variable(Types[0], "ret" + VariablePostfix);
+}
+
+void Intrinsic::emitPrototype(StringRef NamePrefix) {
+  if (UseMacro)
+    OS << "#define ";
+  else
+    OS << "__ai " << Types[0].str() << " ";
+
+  OS << NamePrefix.str() << mangleName(Name, ClassS) << "(";
+
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    if (I != 0)
+      OS << ", ";
+
+    char NameC = '0' + I;
+    std::string Name = "p";
+    Name.push_back(NameC);
+    assert(Variables.find(Name) != Variables.end());
+    Variable &V = Variables[Name];
+
+    if (!UseMacro)
+      OS << V.getType().str() << " ";
+    OS << V.getName();
+  }
+
+  OS << ")";
+}
+
+void Intrinsic::emitOpeningBrace() {
+  if (UseMacro)
+    OS << " __extension__ ({";
+  else
+    OS << " {";
+  emitNewLine();
+}
+
+void Intrinsic::emitClosingBrace() {
+  if (UseMacro)
+    OS << "})";
+  else
+    OS << "}";
+}
+
+void Intrinsic::emitNewLine() {
+  if (UseMacro)
+    OS << " \\\n";
+  else
+    OS << "\n";
+}
+
+void Intrinsic::emitReverseVariable(Variable &Dest, Variable &Src) {
+  if (Dest.getType().getNumVectors() > 1) {
+    emitNewLine();
+
+    for (unsigned K = 0; K < Dest.getType().getNumVectors(); ++K) {
+      OS << "  " << Dest.getName() << ".val[" << utostr(K) << "] = "
+         << "__builtin_shufflevector("
+         << Src.getName() << ".val[" << utostr(K) << "], "
+         << Src.getName() << ".val[" << utostr(K) << "]";
+      for (int J = Dest.getType().getNumElements() - 1; J >= 0; --J)
+        OS << ", " << utostr(J);
+      OS << ");";
+      emitNewLine();
+    }
   } else {
-
-    // Handle normal loads and stores.
-    RegisterSuffix += "{";
-    for (size_t i = 0; i < Count; i++) {
-      RegisterSuffix += "d{{[0-9]+}}";
-      if (HasDupPostfix) {
-        RegisterSuffix += "[]";
-      }
-      if (HasLanePostfix) {
-        RegisterSuffix += "[{{[0-9]+}}]";
-      }
-      if (IsQuad && !HasLanePostfix) {
-        RegisterSuffix += ", d{{[0-9]+}}";
-        if (HasDupPostfix) {
-          RegisterSuffix += "[]";
-        }
-      }
-      if (i < Count-1) {
-        RegisterSuffix += ", ";
-      }
-    }
-    RegisterSuffix += "}, [r{{[0-9]+}}";
-
-    // We only include the alignment hint if we have a vld1.*64 or
-    // a dup/lane instruction.
-    if (IsLDSTOne) {
-      if ((HasLanePostfix || HasDupPostfix) && OutTypeCode != "8") {
-        RegisterSuffix += ":" + OutTypeCode;
-      }
-    }
-
-    RegisterSuffix += "]";
+    OS << "  " << Dest.getName()
+       << " = __builtin_shufflevector(" << Src.getName() << ", " << Src.getName();
+    for (int J = Dest.getType().getNumElements() - 1; J >= 0; --J)
+      OS << ", " << utostr(J);
+    OS << ");";
+    emitNewLine();
   }
 }
 
-static bool HasNPostfixAndScalarArgs(const StringRef &NameRef,
-                                     const bool &HasNPostfix) {
-  return (NameRef.count("vmla") ||
-          NameRef.count("vmlal") ||
-          NameRef.count("vmlsl") ||
-          NameRef.count("vmull") ||
-          NameRef.count("vqdmlal") ||
-          NameRef.count("vqdmlsl") ||
-          NameRef.count("vqdmulh") ||
-          NameRef.count("vqdmull") ||
-          NameRef.count("vqrdmulh")) && HasNPostfix;
-}
-
-static bool IsFiveOperandLaneAccumulator(const StringRef &NameRef,
-                                         const bool &HasLanePostfix) {
-  return (NameRef.count("vmla") ||
-          NameRef.count("vmls") ||
-          NameRef.count("vmlal") ||
-          NameRef.count("vmlsl") ||
-          (NameRef.count("vmul") && NameRef.size() == 3)||
-          NameRef.count("vqdmlal") ||
-          NameRef.count("vqdmlsl") ||
-          NameRef.count("vqdmulh") ||
-          NameRef.count("vqrdmulh")) && HasLanePostfix;
-}
-
-static bool IsSpecialLaneMultiply(const StringRef &NameRef,
-                                  const bool &HasLanePostfix,
-                                  const bool &IsQuad) {
-  const bool IsVMulOrMulh = (NameRef.count("vmul") || NameRef.count("mulh"))
-                               && IsQuad;
-  const bool IsVMull = NameRef.count("mull") && !IsQuad;
-  return (IsVMulOrMulh || IsVMull) && HasLanePostfix;
-}
-
-static void NormalizeProtoForRegisterPatternCreation(const std::string &Name,
-                                                     const std::string &Proto,
-                                                     const bool &HasNPostfix,
-                                                     const bool &IsQuad,
-                                                     const bool &HasLanePostfix,
-                                                     const bool &HasDupPostfix,
-                                                     std::string &NormedProto) {
-  // Handle generic case.
-  const StringRef NameRef(Name);
-  for (size_t i = 0, end = Proto.size(); i < end; i++) {
-    switch (Proto[i]) {
-    case 'u':
-    case 'f':
-    case 'F':
-    case 'd':
-    case 's':
-    case 'x':
-    case 't':
-    case 'n':
-      NormedProto += IsQuad? 'q' : 'd';
-      break;
-    case 'w':
-    case 'k':
-      NormedProto += 'q';
-      break;
-    case 'g':
-    case 'j':
-    case 'h':
-    case 'e':
-      NormedProto += 'd';
-      break;
-    case 'i':
-      NormedProto += HasLanePostfix? 'a' : 'i';
-      break;
-    case 'a':
-      if (HasLanePostfix) {
-        NormedProto += 'a';
-      } else if (HasNPostfixAndScalarArgs(NameRef, HasNPostfix)) {
-        NormedProto += IsQuad? 'q' : 'd';
-      } else {
-        NormedProto += 'i';
-      }
-      break;
-    }
-  }
-
-  // Handle Special Cases.
-  const bool IsNotVExt = !NameRef.count("vext");
-  const bool IsVPADAL = NameRef.count("vpadal");
-  const bool Is5OpLaneAccum = IsFiveOperandLaneAccumulator(NameRef,
-                                                           HasLanePostfix);
-  const bool IsSpecialLaneMul = IsSpecialLaneMultiply(NameRef, HasLanePostfix,
-                                                      IsQuad);
-
-  if (IsSpecialLaneMul) {
-    // If
-    NormedProto[2] = NormedProto[3];
-    NormedProto.erase(3);
-  } else if (NormedProto.size() == 4 &&
-             NormedProto[0] == NormedProto[1] &&
-             IsNotVExt) {
-    // If NormedProto.size() == 4 and the first two proto characters are the
-    // same, ignore the first.
-    NormedProto = NormedProto.substr(1, 3);
-  } else if (Is5OpLaneAccum) {
-    // If we have a 5 op lane accumulator operation, we take characters 1,2,4
-    std::string tmp = NormedProto.substr(1,2);
-    tmp += NormedProto[4];
-    NormedProto = tmp;
-  } else if (IsVPADAL) {
-    // If we have VPADAL, ignore the first character.
-    NormedProto = NormedProto.substr(0, 2);
-  } else if (NameRef.count("vdup") && NormedProto.size() > 2) {
-    // If our instruction is a dup instruction, keep only the first and
-    // last characters.
-    std::string tmp = "";
-    tmp += NormedProto[0];
-    tmp += NormedProto[NormedProto.size()-1];
-    NormedProto = tmp;
-  }
-}
-
-/// GenerateRegisterCheckPatterns - Given a bunch of data we have
-/// extracted, generate a FileCheck pattern to check that an
-/// instruction's arguments are correct.
-static void GenerateRegisterCheckPattern(const std::string &Name,
-                                         const std::string &Proto,
-                                         const std::string &OutTypeCode,
-                                         const bool &HasNPostfix,
-                                         const bool &IsQuad,
-                                         const bool &HasLanePostfix,
-                                         const bool &HasDupPostfix,
-                                         const size_t &TBNumber,
-                                         std::string &RegisterSuffix) {
-
-  RegisterSuffix = "";
-
-  const StringRef NameRef(Name);
-
-  if ((NameRef.count("vdup") || NameRef.count("vmov")) && HasNPostfix) {
-    return;
-  }
-
-  const bool IsLoadStore = NameRef.count("vld") || NameRef.count("vst");
-  const bool IsTBXOrTBL = NameRef.count("vtbl") || NameRef.count("vtbx");
-
-  if (IsLoadStore) {
-    // Grab N value from  v{ld,st}N using its ascii representation.
-    const size_t Count = NameRef[3] - 48;
-
-    GenerateRegisterCheckPatternForLoadStores(NameRef, OutTypeCode, IsQuad,
-                                              HasDupPostfix, HasLanePostfix,
-                                              Count, RegisterSuffix);
-  } else if (IsTBXOrTBL) {
-    RegisterSuffix += "d{{[0-9]+}}, {";
-    for (size_t i = 0; i < TBNumber-1; i++) {
-      RegisterSuffix += "d{{[0-9]+}}, ";
-    }
-    RegisterSuffix += "d{{[0-9]+}}}, d{{[0-9]+}}";
-  } else {
-    // Handle a normal instruction.
-    if (NameRef.count("vget") || NameRef.count("vset"))
-      return;
-
-    // We first normalize our proto, since we only need to emit 4
-    // different types of checks, yet have more than 4 proto types
-    // that map onto those 4 patterns.
-    std::string NormalizedProto("");
-    NormalizeProtoForRegisterPatternCreation(Name, Proto, HasNPostfix, IsQuad,
-                                             HasLanePostfix, HasDupPostfix,
-                                             NormalizedProto);
-
-    for (size_t i = 0, end = NormalizedProto.size(); i < end; i++) {
-      const char &c = NormalizedProto[i];
-      switch (c) {
-      case 'q':
-        RegisterSuffix += "q{{[0-9]+}}, ";
-        break;
-
-      case 'd':
-        RegisterSuffix += "d{{[0-9]+}}, ";
-        break;
-
-      case 'i':
-        RegisterSuffix += "#{{[0-9]+}}, ";
-        break;
-
-      case 'a':
-        RegisterSuffix += "d{{[0-9]+}}[{{[0-9]}}], ";
-        break;
-      }
-    }
-
-    // Remove extra ", ".
-    RegisterSuffix = RegisterSuffix.substr(0, RegisterSuffix.size()-2);
-  }
-}
-
-/// GenerateChecksForIntrinsic - Given a specific instruction name +
-/// typestr + class kind, generate the proper set of FileCheck
-/// Patterns to check for. We could just return a string, but instead
-/// use a vector since it provides us with the extra flexibility of
-/// emitting multiple checks, which comes in handy for certain cases
-/// like mla where we want to check for 2 different instructions.
-static void GenerateChecksForIntrinsic(const std::string &Name,
-                                       const std::string &Proto,
-                                       StringRef &OutTypeStr,
-                                       StringRef &InTypeStr,
-                                       ClassKind Ck,
-                                       const std::string &InstName,
-                                       bool IsHiddenLOp,
-                                       std::vector<std::string>& Result) {
-
-  // If Ck is a ClassNoTest instruction, just return so no test is
-  // emitted.
-  if(Ck == ClassNoTest)
+void Intrinsic::emitArgumentReversal() {
+  if (BigEndianSafe)
     return;
 
-  if (Name == "vcvt_f32_f16") {
-    Result.push_back("vcvt.f32.f16");
-    return;
+  // Reverse all vector arguments.
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    std::string Name = "p" + utostr(I);
+    std::string NewName = "rev" + utostr(I);
+
+    Variable &V = Variables[Name];
+    Variable NewV(V.getType(), NewName + VariablePostfix);
+
+    if (!NewV.getType().isVector() || NewV.getType().getNumElements() == 1)
+      continue;
+
+    OS << "  " << NewV.getType().str() << " " << NewV.getName() << ";";
+    emitReverseVariable(NewV, V);
+    V = NewV;
   }
-
-
-  // Now we preprocess our instruction given the data we have to get the
-  // data that we need.
-  // Create a StringRef for String Manipulation of our Name.
-  const StringRef NameRef(Name);
-  // Instruction Prefix.
-  std::string Prefix;
-  // The type code for our out type string.
-  std::string OutTypeCode;
-  // To handle our different cases, we need to check for different postfixes.
-  // Is our instruction a quad instruction.
-  bool IsQuad = false;
-  // Our instruction is of the form <instructionname>_n.
-  bool HasNPostfix = false;
-  // Our instruction is of the form <instructionname>_lane.
-  bool HasLanePostfix = false;
-  // Our instruction is of the form <instructionname>_dup.
-  bool HasDupPostfix  = false;
-  // Our instruction is a vcvt instruction which requires special handling.
-  bool IsSpecialVCvt = false;
-  // If we have a vtbxN or vtblN instruction, this is set to N.
-  size_t TBNumber = -1;
-  // Register Suffix
-  std::string RegisterSuffix;
-
-  PreprocessInstruction(NameRef, InstName, Prefix,
-                        HasNPostfix, HasLanePostfix, HasDupPostfix,
-                        IsSpecialVCvt, TBNumber);
-
-  InstructionTypeCode(OutTypeStr, Ck, IsQuad, OutTypeCode);
-  GenerateRegisterCheckPattern(Name, Proto, OutTypeCode, HasNPostfix, IsQuad,
-                               HasLanePostfix, HasDupPostfix, TBNumber,
-                               RegisterSuffix);
-
-  // In the following section, we handle a bunch of special cases. You can tell
-  // a special case by the fact we are returning early.
-
-  // If our instruction is a logical instruction without postfix or a
-  // hidden LOp just return the current Prefix.
-  if (Ck == ClassL || IsHiddenLOp) {
-    Result.push_back(Prefix + " " + RegisterSuffix);
-    return;
-  }
-
-  // If we have a vmov, due to the many different cases, some of which
-  // vary within the different intrinsics generated for a single
-  // instruction type, just output a vmov. (e.g. given an instruction
-  // A, A.u32 might be vmov and A.u8 might be vmov.8).
-  //
-  // FIXME: Maybe something can be done about this. The two cases that we care
-  // about are vmov as an LType and vmov as a WType.
-  if (Prefix == "vmov") {
-    Result.push_back(Prefix + " " + RegisterSuffix);
-    return;
-  }
-
-  // In the following section, we handle special cases.
-
-  if (OutTypeCode == "64") {
-    // If we have a 64 bit vdup/vext and are handling an uint64x1_t
-    // type, the intrinsic will be optimized away, so just return
-    // nothing.  On the other hand if we are handling an uint64x2_t
-    // (i.e. quad instruction), vdup/vmov instructions should be
-    // emitted.
-    if (Prefix == "vdup" || Prefix == "vext") {
-      if (IsQuad) {
-        Result.push_back("{{vmov|vdup}}");
-      }
-      return;
-    }
-
-    // v{st,ld}{2,3,4}_{u,s}64 emit v{st,ld}1.64 instructions with
-    // multiple register operands.
-    bool MultiLoadPrefix = Prefix == "vld2" || Prefix == "vld3"
-                            || Prefix == "vld4";
-    bool MultiStorePrefix = Prefix == "vst2" || Prefix == "vst3"
-                            || Prefix == "vst4";
-    if (MultiLoadPrefix || MultiStorePrefix) {
-      Result.push_back(NameRef.slice(0, 3).str() + "1.64");
-      return;
-    }
-
-    // v{st,ld}1_{lane,dup}_{u64,s64} use vldr/vstr/vmov/str instead of
-    // emitting said instructions. So return a check for
-    // vldr/vstr/vmov/str instead.
-    if (HasLanePostfix || HasDupPostfix) {
-      if (Prefix == "vst1") {
-        Result.push_back("{{str|vstr|vmov}}");
-        return;
-      } else if (Prefix == "vld1") {
-        Result.push_back("{{ldr|vldr|vmov}}");
-        return;
-      }
-    }
-  }
-
-  // vzip.32/vuzp.32 are the same instruction as vtrn.32 and are
-  // sometimes disassembled as vtrn.32. We use a regex to handle both
-  // cases.
-  if ((Prefix == "vzip" || Prefix == "vuzp") && OutTypeCode == "32") {
-    Result.push_back("{{vtrn|" + Prefix + "}}.32 " + RegisterSuffix);
-    return;
-  }
-
-  // Currently on most ARM processors, we do not use vmla/vmls for
-  // quad floating point operations. Instead we output vmul + vadd. So
-  // check if we have one of those instructions and just output a
-  // check for vmul.
-  if (OutTypeCode == "f32") {
-    if (Prefix == "vmls") {
-      Result.push_back("vmul." + OutTypeCode + " " + RegisterSuffix);
-      Result.push_back("vsub." + OutTypeCode);
-      return;
-    } else if (Prefix == "vmla") {
-      Result.push_back("vmul." + OutTypeCode + " " + RegisterSuffix);
-      Result.push_back("vadd." + OutTypeCode);
-      return;
-    }
-  }
-
-  // If we have vcvt, get the input type from the instruction name
-  // (which should be of the form instname_inputtype) and append it
-  // before the output type.
-  if (Prefix == "vcvt") {
-    const std::string inTypeCode = NameRef.substr(NameRef.find_last_of("_")+1);
-    Prefix += "." + inTypeCode;
-  }
-
-  // Append output type code to get our final mangled instruction.
-  Prefix += "." + OutTypeCode;
-
-  Result.push_back(Prefix + " " + RegisterSuffix);
 }
 
-/// UseMacro - Examine the prototype string to determine if the intrinsic
-/// should be defined as a preprocessor macro instead of an inline function.
-static bool UseMacro(const std::string &proto, StringRef typestr) {
-  // If this builtin takes an immediate argument, we need to #define it rather
-  // than use a standard declaration, so that SemaChecking can range check
-  // the immediate passed by the user.
-  if (proto.find('i') != std::string::npos)
-    return true;
-
-  // Pointer arguments need to use macros to avoid hiding aligned attributes
-  // from the pointer type.
-  if (proto.find('p') != std::string::npos ||
-      proto.find('c') != std::string::npos)
-    return true;
-
-  // It is not permitted to pass or return an __fp16 by value, so intrinsics
-  // taking a scalar float16_t must be implemented as macros.
-  if (typestr.find('h') != std::string::npos &&
-      proto.find('s') != std::string::npos)
-    return true;
-
-  return false;
+void Intrinsic::emitReturnReversal() {
+  if (BigEndianSafe)
+    return;
+  if (!getReturnType().isVector() || getReturnType().isVoid() ||
+      getReturnType().getNumElements() == 1)
+    return;
+  emitReverseVariable(RetVar, RetVar);
 }
 
-/// MacroArgUsedDirectly - Return true if argument i for an intrinsic that is
-/// defined as a macro should be accessed directly instead of being first
-/// assigned to a local temporary.
-static bool MacroArgUsedDirectly(const std::string &proto, unsigned i) {
-  // True for constant ints (i), pointers (p) and const pointers (c).
-  return (proto[i] == 'i' || proto[i] == 'p' || proto[i] == 'c');
-}
 
-// Generate the string "(argtype a, argtype b, ...)"
-static std::string GenArgs(const std::string &proto, StringRef typestr,
-                           const std::string &name) {
-  bool define = UseMacro(proto, typestr);
-  char arg = 'a';
+void Intrinsic::emitShadowedArgs() {
+  // Macro arguments are not type-checked like inline function arguments,
+  // so assign them to local temporaries to get the right type checking.
+  if (!UseMacro)
+    return;
 
-  std::string s;
-  s += "(";
-
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    if (define) {
-      // Some macro arguments are used directly instead of being assigned
-      // to local temporaries; prepend an underscore prefix to make their
-      // names consistent with the local temporaries.
-      if (MacroArgUsedDirectly(proto, i))
-        s += "__";
-    } else {
-      s += TypeString(proto[i], typestr) + " __";
-    }
-    s.push_back(arg);
-    if ((i + 1) < e)
-      s += ", ";
-  }
-
-  s += ")";
-  return s;
-}
-
-// Macro arguments are not type-checked like inline function arguments, so
-// assign them to local temporaries to get the right type checking.
-static std::string GenMacroLocals(const std::string &proto, StringRef typestr,
-                                  const std::string &name ) {
-  char arg = 'a';
-  std::string s;
-  bool generatedLocal = false;
-
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
+  for (unsigned I = 0; I < getNumParams(); ++I) {
     // Do not create a temporary for an immediate argument.
     // That would defeat the whole point of using a macro!
-    if (MacroArgUsedDirectly(proto, i))
+    if (hasImmediate() && Proto[I+1] == 'i')
       continue;
-    generatedLocal = true;
-    s += TypeString(proto[i], typestr) + " __";
-    s.push_back(arg);
-    s += " = (";
-    s.push_back(arg);
-    s += "); ";
-  }
+    // Do not create a temporary for pointer arguments. The input
+    // pointer may have an alignment hint.
+    if (getParamType(I).isPointer())
+      continue;
 
-  if (generatedLocal)
-    s += "\\\n  ";
-  return s;
-}
+    std::string Name = "p" + utostr(I);
 
-// Use the vmovl builtin to sign-extend or zero-extend a vector.
-static std::string Extend(StringRef typestr, const std::string &a, bool h=0) {
-  std::string s, high;
-  high = h ? "_high" : "";
-  s = MangleName("vmovl" + high, typestr, ClassS);
-  s += "(" + a + ")";
-  return s;
-}
+    assert(Variables.find(Name) != Variables.end());
+    Variable &V = Variables[Name];
 
-// Get the high 64-bit part of a vector
-static std::string GetHigh(const std::string &a, StringRef typestr) {
-  std::string s;
-  s = MangleName("vget_high", typestr, ClassS);
-  s += "(" + a + ")";
-  return s;
-}
+    std::string NewName = "s" + utostr(I);
+    Variable V2(V.getType(), NewName + VariablePostfix);
 
-// Gen operation with two operands and get high 64-bit for both of two operands.
-static std::string Gen2OpWith2High(StringRef typestr,
-                                   const std::string &op,
-                                   const std::string &a,
-                                   const std::string &b) {
-  std::string s;
-  std::string Op1 = GetHigh(a, typestr);
-  std::string Op2 = GetHigh(b, typestr);
-  s = MangleName(op, typestr, ClassS);
-  s += "(" + Op1 + ", " + Op2 + ");";
-  return s;
-}
+    OS << "  " << V2.getType().str() << " " << V2.getName() << " = "
+       << V.getName() << ";";
+    emitNewLine();
 
-// Gen operation with three operands and get high 64-bit of the latter 
-// two operands.
-static std::string Gen3OpWith2High(StringRef typestr,
-                                   const std::string &op,
-                                   const std::string &a,
-                                   const std::string &b,
-                                   const std::string &c) {
-  std::string s;
-  std::string Op1 = GetHigh(b, typestr);
-  std::string Op2 = GetHigh(c, typestr);
-  s = MangleName(op, typestr, ClassS);
-  s += "(" + a + ", " + Op1 + ", " + Op2 + ");";
-  return s;
-}
-
-// Gen combine operation by putting a on low 64-bit, and b on high 64-bit.
-static std::string GenCombine(std::string typestr,
-                              const std::string &a,
-                              const std::string &b) {
-  std::string s;
-  s = MangleName("vcombine", typestr, ClassS);
-  s += "(" + a + ", " + b + ")";
-  return s;
-}
-
-static std::string Duplicate(unsigned nElts, StringRef typestr,
-                             const std::string &a) {
-  std::string s;
-
-  s = "(" + TypeString('d', typestr) + "){ ";
-  for (unsigned i = 0; i != nElts; ++i) {
-    s += a;
-    if ((i + 1) < nElts)
-      s += ", ";
+    V = V2;
   }
-  s += " }";
-
-  return s;
-}
-
-static std::string SplatLane(unsigned nElts, const std::string &vec,
-                             const std::string &lane) {
-  std::string s = "__builtin_shufflevector(" + vec + ", " + vec;
-  for (unsigned i = 0; i < nElts; ++i)
-    s += ", " + lane;
-  s += ")";
-  return s;
-}
-
-static std::string RemoveHigh(const std::string &name) {
-  std::string s = name;
-  std::size_t found = s.find("_high_");
-  if (found == std::string::npos)
-    PrintFatalError("name should contain \"_high_\" for high intrinsics");
-  s.replace(found, 5, "");
-  return s;
-}
-
-static unsigned GetNumElements(StringRef typestr, bool &quad) {
-  quad = false;
-  bool dummy = false;
-  char type = ClassifyType(typestr, quad, dummy, dummy);
-  unsigned nElts = 0;
-  switch (type) {
-  case 'c': nElts = 8; break;
-  case 's': nElts = 4; break;
-  case 'i': nElts = 2; break;
-  case 'l': nElts = 1; break;
-  case 'k': nElts = 1; break;
-  case 'h': nElts = 4; break;
-  case 'f': nElts = 2; break;
-  case 'd':
-    nElts = 1;
-    break;
-  default:
-    PrintFatalError("unhandled type!");
-  }
-  if (quad) nElts <<= 1;
-  return nElts;
-}
-
-// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
-//
-// Note that some intrinsic definitions around 'lane' are being implemented
-// with macros, because they all contain constant integer argument, and we
-// statically check the range of the lane index to meet the semantic
-// requirement of different intrinsics.
-//
-// For the intrinsics implemented with macro, if they contain another intrinsic
-// implemented with maco, we have to avoid using the same argument names for
-// the nested instrinsics. For example, macro vfms_lane is being implemented
-// with another macor vfma_lane, so we rename all arguments for vfms_lane by
-// adding a suffix '1'.
-
-static std::string GenOpString(const std::string &name, OpKind op,
-                               const std::string &proto, StringRef typestr) {
-  bool quad;
-  unsigned nElts = GetNumElements(typestr, quad);
-  bool define = UseMacro(proto, typestr);
-
-  std::string ts = TypeString(proto[0], typestr);
-  std::string s;
-  if (!define) {
-    s = "return ";
-  }
-
-  switch(op) {
-  case OpAdd:
-    s += "__a + __b;";
-    break;
-  case OpAddl:
-    s += Extend(typestr, "__a") + " + " + Extend(typestr, "__b") + ";";
-    break;
-  case OpAddlHi:
-    s += Extend(typestr, "__a", 1) + " + " + Extend(typestr, "__b", 1) + ";";
-    break;
-  case OpAddw:
-    s += "__a + " + Extend(typestr, "__b") + ";";
-    break;
-  case OpAddwHi:
-    s += "__a + " + Extend(typestr, "__b", 1) + ";";
-    break;
-  case OpSub:
-    s += "__a - __b;";
-    break;
-  case OpSubl:
-    s += Extend(typestr, "__a") + " - " + Extend(typestr, "__b") + ";";
-    break;
-  case OpSublHi:
-    s += Extend(typestr, "__a", 1) + " - " + Extend(typestr, "__b", 1) + ";";
-    break;
-  case OpSubw:
-    s += "__a - " + Extend(typestr, "__b") + ";";
-    break;
-  case OpSubwHi:
-    s += "__a - " + Extend(typestr, "__b", 1) + ";";
-    break;
-  case OpMulN:
-    s += "__a * " + Duplicate(nElts, typestr, "__b") + ";";
-    break;
-  case OpMulLane:
-    s += "__a * " + SplatLane(nElts, "__b", "__c") + ";";
-    break;
-  case OpMulXLane:
-    s += MangleName("vmulx", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpMul:
-    s += "__a * __b;";
-    break;
-  case OpFMlaN:
-    s += MangleName("vfma", typestr, ClassS);
-    s += "(__a, __b, " + Duplicate(nElts,typestr, "__c") + ");";
-    break;
-  case OpFMlsN:
-    s += MangleName("vfms", typestr, ClassS);
-    s += "(__a, __b, " + Duplicate(nElts,typestr, "__c") + ");";
-    break;
-  case OpMullLane:
-    s += MangleName("vmull", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpMullHiLane:
-    s += MangleName("vmull", typestr, ClassS) + "(" +
-      GetHigh("__a", typestr) + ", " + SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpMlaN:
-    s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");";
-    break;
-  case OpMlaLane:
-    s += "__a + (__b * " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMla:
-    s += "__a + (__b * __c);";
-    break;
-  case OpMlalN:
-    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " +
-      Duplicate(nElts, typestr, "__c") + ");";
-    break;
-  case OpMlalLane:
-    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " +
-      SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMlalHiLane:
-    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(" +
-      GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMlal:
-    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, __c);";
-    break;
-  case OpMullHi:
-    s += Gen2OpWith2High(typestr, "vmull", "__a", "__b");
-    break;
-  case OpMullHiP64: {
-    std::string Op1 = GetHigh("__a", typestr);
-    std::string Op2 = GetHigh("__b", typestr);
-    s += MangleName("vmull", typestr, ClassS);
-    s += "((poly64_t)" + Op1 + ", (poly64_t)" + Op2 + ");";
-    break;
-  }
-  case OpMullHiN:
-    s += MangleName("vmull_n", typestr, ClassS);
-    s += "(" + GetHigh("__a", typestr) + ", __b);";
-    return s;
-  case OpMlalHi:
-    s += Gen3OpWith2High(typestr, "vmlal", "__a", "__b", "__c");
-    break;
-  case OpMlalHiN:
-    s += MangleName("vmlal_n", typestr, ClassS);
-    s += "(__a, " + GetHigh("__b", typestr) + ", __c);";
-    return s;
-  case OpMlsN:
-    s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");";
-    break;
-  case OpMlsLane:
-    s += "__a - (__b * " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpFMSLane:
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
-    s += MangleName("vfma_lane", typestr, ClassS) + "(__a1, __b1, -__c1, __d);";
-    break;
-  case OpFMSLaneQ:
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
-    s += MangleName("vfma_laneq", typestr, ClassS) + "(__a1, __b1, -__c1, __d);";
-    break;
-  case OpMls:
-    s += "__a - (__b * __c);";
-    break;
-  case OpMlslN:
-    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " +
-      Duplicate(nElts, typestr, "__c") + ");";
-    break;
-  case OpMlslLane:
-    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " +
-      SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMlslHiLane:
-    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(" +
-      GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMlsl:
-    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, __c);";
-    break;
-  case OpMlslHi:
-    s += Gen3OpWith2High(typestr, "vmlsl", "__a", "__b", "__c");
-    break;
-  case OpMlslHiN:
-    s += MangleName("vmlsl_n", typestr, ClassS);
-    s += "(__a, " + GetHigh("__b", typestr) + ", __c);";
-    break;
-  case OpQDMullLane:
-    s += MangleName("vqdmull", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpQDMullHiLane:
-    s += MangleName("vqdmull", typestr, ClassS) + "(" +
-      GetHigh("__a", typestr) + ", " + SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpQDMlalLane:
-    s += MangleName("vqdmlal", typestr, ClassS) + "(__a, __b, " +
-      SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpQDMlalHiLane:
-    s += MangleName("vqdmlal", typestr, ClassS) + "(__a, " +
-      GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpQDMlslLane:
-    s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, __b, " +
-      SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpQDMlslHiLane:
-    s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, " +
-      GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpQDMulhLane:
-    s += MangleName("vqdmulh", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpQRDMulhLane:
-    s += MangleName("vqrdmulh", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpEq:
-    s += "(" + ts + ")(__a == __b);";
-    break;
-  case OpGe:
-    s += "(" + ts + ")(__a >= __b);";
-    break;
-  case OpLe:
-    s += "(" + ts + ")(__a <= __b);";
-    break;
-  case OpGt:
-    s += "(" + ts + ")(__a > __b);";
-    break;
-  case OpLt:
-    s += "(" + ts + ")(__a < __b);";
-    break;
-  case OpNeg:
-    s += " -__a;";
-    break;
-  case OpNot:
-    s += " ~__a;";
-    break;
-  case OpAnd:
-    s += "__a & __b;";
-    break;
-  case OpOr:
-    s += "__a | __b;";
-    break;
-  case OpXor:
-    s += "__a ^ __b;";
-    break;
-  case OpAndNot:
-    s += "__a & ~__b;";
-    break;
-  case OpOrNot:
-    s += "__a | ~__b;";
-    break;
-  case OpCast:
-    s += "(" + ts + ")__a;";
-    break;
-  case OpConcat:
-    s += "(" + ts + ")__builtin_shufflevector((int64x1_t)__a";
-    s += ", (int64x1_t)__b, 0, 1);";
-    break;
-  case OpHi:
-    // nElts is for the result vector, so the source is twice that number.
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = nElts; i < nElts * 2; ++i)
-      s += ", " + utostr(i);
-    s+= ");";
-    break;
-  case OpLo:
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = 0; i < nElts; ++i)
-      s += ", " + utostr(i);
-    s+= ");";
-    break;
-  case OpDup:
-    s += Duplicate(nElts, typestr, "__a") + ";";
-    break;
-  case OpDupLane:
-    s += SplatLane(nElts, "__a", "__b") + ";";
-    break;
-  case OpSelect:
-    // ((0 & 1) | (~0 & 2))
-    s += "(" + ts + ")";
-    ts = TypeString(proto[1], typestr);
-    s += "((__a & (" + ts + ")__b) | ";
-    s += "(~__a & (" + ts + ")__c));";
-    break;
-  case OpRev16:
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = 2; i <= nElts; i += 2)
-      for (unsigned j = 0; j != 2; ++j)
-        s += ", " + utostr(i - j - 1);
-    s += ");";
-    break;
-  case OpRev32: {
-    unsigned WordElts = nElts >> (1 + (int)quad);
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = WordElts; i <= nElts; i += WordElts)
-      for (unsigned j = 0; j != WordElts; ++j)
-        s += ", " + utostr(i - j - 1);
-    s += ");";
-    break;
-  }
-  case OpRev64: {
-    unsigned DblWordElts = nElts >> (int)quad;
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = DblWordElts; i <= nElts; i += DblWordElts)
-      for (unsigned j = 0; j != DblWordElts; ++j)
-        s += ", " + utostr(i - j - 1);
-    s += ");";
-    break;
-  }
-  case OpXtnHi: {
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName("vmovn", typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpSqxtunHi: {
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName("vqmovun", typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpQxtnHi: {
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName("vqmovn", typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpFcvtnHi: {
-    std::string FName = (nElts == 1) ? "vcvt_f32" : "vcvt_f16";
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName(FName, typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpFcvtlHi: {
-    std::string FName = (nElts == 2) ? "vcvt_f64" : "vcvt_f32";
-    s = TypeString('d', typestr) + " __a1 = " + GetHigh("__a", typestr) +
-        ";\n  return " + MangleName(FName, typestr, ClassS) + "(__a1);";
-    break;
-  }
-  case OpFcvtxnHi: {
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName("vcvtx_f32", typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpUzp1:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < nElts; i++)
-      s += ", " + utostr(2*i);
-    s += ");";
-    break;
-  case OpUzp2:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < nElts; i++)
-      s += ", " + utostr(2*i+1);
-    s += ");";
-    break;
-  case OpZip1:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < (nElts/2); i++)
-       s += ", " + utostr(i) + ", " + utostr(i+nElts);
-    s += ");";
-    break;
-  case OpZip2:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = nElts/2; i < nElts; i++)
-       s += ", " + utostr(i) + ", " + utostr(i+nElts);
-    s += ");";
-    break;
-  case OpTrn1:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < (nElts/2); i++)
-       s += ", " + utostr(2*i) + ", " + utostr(2*i+nElts);
-    s += ");";
-    break;
-  case OpTrn2:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < (nElts/2); i++)
-       s += ", " + utostr(2*i+1) + ", " + utostr(2*i+1+nElts);
-    s += ");";
-    break;
-  case OpAbdl: {
-    std::string abd = MangleName("vabd", typestr, ClassS) + "(__a, __b)";
-    if (typestr[0] != 'U') {
-      // vabd results are always unsigned and must be zero-extended.
-      std::string utype = "U" + typestr.str();
-      s += "(" + TypeString(proto[0], typestr) + ")";
-      abd = "(" + TypeString('d', utype) + ")" + abd;
-      s += Extend(utype, abd) + ";";
-    } else {
-      s += Extend(typestr, abd) + ";";
-    }
-    break;
-  }
-  case OpAbdlHi:
-    s += Gen2OpWith2High(typestr, "vabdl", "__a", "__b");
-    break;
-  case OpAddhnHi: {
-    std::string addhn = MangleName("vaddhn", typestr, ClassS) + "(__b, __c)";
-    s += GenCombine(GetNarrowTypestr(typestr), "__a", addhn);
-    s += ";";
-    break;
-  }
-  case OpRAddhnHi: {
-    std::string raddhn = MangleName("vraddhn", typestr, ClassS) + "(__b, __c)";
-    s += GenCombine(GetNarrowTypestr(typestr), "__a", raddhn);
-    s += ";";
-    break;
-  }
-  case OpSubhnHi: {
-    std::string subhn = MangleName("vsubhn", typestr, ClassS) + "(__b, __c)";
-    s += GenCombine(GetNarrowTypestr(typestr), "__a", subhn);
-    s += ";";
-    break;
-  }
-  case OpRSubhnHi: {
-    std::string rsubhn = MangleName("vrsubhn", typestr, ClassS) + "(__b, __c)";
-    s += GenCombine(GetNarrowTypestr(typestr), "__a", rsubhn);
-    s += ";";
-    break;
-  }
-  case OpAba:
-    s += "__a + " + MangleName("vabd", typestr, ClassS) + "(__b, __c);";
-    break;
-  case OpAbal:
-    s += "__a + " + MangleName("vabdl", typestr, ClassS) + "(__b, __c);";
-    break;
-  case OpAbalHi:
-    s += Gen3OpWith2High(typestr, "vabal", "__a", "__b", "__c");
-    break;
-  case OpQDMullHi:
-    s += Gen2OpWith2High(typestr, "vqdmull", "__a", "__b");
-    break;
-  case OpQDMullHiN:
-    s += MangleName("vqdmull_n", typestr, ClassS);
-    s += "(" + GetHigh("__a", typestr) + ", __b);";
-    return s;
-  case OpQDMlalHi:
-    s += Gen3OpWith2High(typestr, "vqdmlal", "__a", "__b", "__c");
-    break;
-  case OpQDMlalHiN:
-    s += MangleName("vqdmlal_n", typestr, ClassS);
-    s += "(__a, " + GetHigh("__b", typestr) + ", __c);";
-    return s;
-  case OpQDMlslHi:
-    s += Gen3OpWith2High(typestr, "vqdmlsl", "__a", "__b", "__c");
-    break;
-  case OpQDMlslHiN:
-    s += MangleName("vqdmlsl_n", typestr, ClassS);
-    s += "(__a, " + GetHigh("__b", typestr) + ", __c);";
-    return s;
-  case OpDiv:
-    s += "__a / __b;";
-    break;
-  case OpMovlHi: {
-    s = TypeString(proto[1], typestr.drop_front()) + " __a1 = " +
-        MangleName("vget_high", typestr, ClassS) + "(__a);\n  " + s;
-    s += "(" + ts + ")" + MangleName("vshll_n", typestr, ClassS);
-    s += "(__a1, 0);";
-    break;
-  }
-  case OpLongHi: {
-    // Another local variable __a1 is needed for calling a Macro,
-    // or using __a will have naming conflict when Macro expanding.
-    s += TypeString(proto[1], typestr.drop_front()) + " __a1 = " +
-         MangleName("vget_high", typestr, ClassS) + "(__a); \\\n";
-    s += "  (" + ts + ")" + MangleName(RemoveHigh(name), typestr, ClassS) +
-         "(__a1, __b);";
-    break;
-  }
-  case OpNarrowHi: {
-    s += "(" + ts + ")" + MangleName("vcombine", typestr, ClassS) + "(__a, " +
-         MangleName(RemoveHigh(name), typestr, ClassS) + "(__b, __c));";
-    break;
-  }
-  case OpCopyLane: {
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
-    s += TypeString('s', typestr) + " __c2 = " +
-         MangleName("vget_lane", typestr, ClassS) + "(__c1, __d); \\\n  " +
-         MangleName("vset_lane", typestr, ClassS) + "(__c2, __a1, __b);";
-    break;
-  }
-  case OpCopyQLane: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
-    s += TypeString('s', typestr) + " __c2 = vget_lane_" + typeCode +
-         "(__c1, __d); \\\n  vsetq_lane_" + typeCode + "(__c2, __a1, __b);";
-    break;
-  }
-  case OpCopyLaneQ: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
-    s += TypeString('s', typestr) + " __c2 = vgetq_lane_" + typeCode +
-         "(__c1, __d); \\\n  vset_lane_" + typeCode + "(__c2, __a1, __b);";
-    break;
-  }
-  case OpScalarMulLane: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode +
-      "(__b, __c);\\\n  __a * __d1;";
-    break;
-  }
-  case OpScalarMulLaneQ: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString('s', typestr) + " __d1 = vgetq_lane_" + typeCode +
-      "(__b1, __c);\\\n  __a1 * __d1;";
-    break;
-  }
-  case OpScalarMulXLane: {
-    bool dummy = false;
-    char type = ClassifyType(typestr, dummy, dummy, dummy);
-    if (type == 'f') type = 's';
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode +
-      "(__b1, __c);\\\n  vmulx" + type + "_" +
-      typeCode +  "(__a1, __d1);";
-    break;
-  }
-  case OpScalarMulXLaneQ: {
-    bool dummy = false;
-    char type = ClassifyType(typestr, dummy, dummy, dummy);
-    if (type == 'f') type = 's';
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString('s', typestr) + " __d1 = vgetq_lane_" +
-      typeCode + "(__b1, __c);\\\n  vmulx" + type +
-      "_" + typeCode +  "(__a1, __d1);";
-    break;
-  }
-
-  case OpScalarVMulXLane: {
-    bool dummy = false;
-    char type = ClassifyType(typestr, dummy, dummy, dummy);
-    if (type == 'f') type = 's';
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString('s', typestr) + " __d1 = vget_lane_" +
-      typeCode + "(__a1, 0);\\\n" +
-      "  " + TypeString('s', typestr) + " __e1 = vget_lane_" +
-      typeCode + "(__b1, __c);\\\n" +
-      "  " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" +
-      typeCode + "(__d1, __e1);\\\n" +
-      "  " + TypeString('d', typestr) + " __g1;\\\n" +
-      "  vset_lane_" + typeCode + "(__f1, __g1, __c);";
-    break;
-  }
-
-  case OpScalarVMulXLaneQ: {
-    bool dummy = false;
-    char type = ClassifyType(typestr, dummy, dummy, dummy);
-    if (type == 'f') type = 's';
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString('s', typestr) + " __d1 = vget_lane_" +
-      typeCode + "(__a1, 0);\\\n" +
-      "  " + TypeString('s', typestr) + " __e1 = vgetq_lane_" +
-      typeCode + "(__b1, __c);\\\n" +
-      "  " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" +
-      typeCode + "(__d1, __e1);\\\n" +
-      "  " + TypeString('d', typestr) + " __g1;\\\n" +
-      "  vset_lane_" + typeCode + "(__f1, __g1, 0);";
-    break;
-  }
-  case OpScalarQDMullLane: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += MangleName("vqdmull", typestr, ClassS) + "(__a1, " +
-    "vget_lane_" + typeCode + "(__b1, __c));";
-    break;
-  }
-  case OpScalarQDMullLaneQ: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += MangleName("vqdmull", typestr, ClassS) + "(__a1, " +
-    "vgetq_lane_" + typeCode + "(__b1, __c));";
-    break;
-  }
-  case OpScalarQDMulHiLane: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += MangleName("vqdmulh", typestr, ClassS) + "(__a1, " +
-    "vget_lane_" + typeCode + "(__b1, __c));";
-    break;
-  }
-  case OpScalarQDMulHiLaneQ: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += MangleName("vqdmulh", typestr, ClassS) + "(__a1, " +
-    "vgetq_lane_" + typeCode + "(__b1, __c));";
-    break;
-  }
-  case OpScalarQRDMulHiLane: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += MangleName("vqrdmulh", typestr, ClassS) + "(__a1, " +
-    "vget_lane_" + typeCode + "(__b1, __c));";
-    break;
-  }
-  case OpScalarQRDMulHiLaneQ: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += MangleName("vqrdmulh", typestr, ClassS) + "(__a1, " +
-    "vgetq_lane_" + typeCode + "(__b1, __c));";
-    break;
-  }
-  case OpScalarGetLane:{
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-
-    std::string intType = quad ? "int16x8_t" : "int16x4_t";
-    std::string intName = quad ? "vgetq" : "vget";
-
-    // reinterpret float16 vector as int16 vector
-    s += intType + " __a2 = *(" + intType + " *)(&__a1);\\\n";
-
-    s += "  int16_t __a3 = " + intName + "_lane_s16(__a2, __b);\\\n";
-
-    // reinterpret int16 vector as float16 vector
-    s += "  float16_t __a4 = *(float16_t *)(&__a3);\\\n";
-    s += "  __a4;";
-    break;
-  }
-  case OpScalarSetLane:{
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString(proto[1], typestr) + " __a1 = __a;\\\n  ";
-
-    std::string origType = quad ? "float16x8_t" : "float16x4_t";
-    std::string intType = quad ? "int16x8_t" : "int16x4_t";
-    std::string intName = quad ? "vsetq" : "vset";
-
-    // reinterpret float16_t as int16_t
-    s += "int16_t __a2 = *(int16_t *)(&__a1);\\\n";
-    // reinterpret float16 vector as int16 vector
-    s += "  " + intType + " __b2 = *(" + intType + " *)(&__b);\\\n";
-
-    s += "  " + intType + " __b3 = " + intName + "_lane_s16(__a2, __b2, __c);\\\n";
-
-    // reinterpret int16 vector as float16 vector
-    s += "  " + origType + " __b4 = *(" + origType + " *)(&__b3);\\\n";
-    s += "__b4;";
-    break;
-  }
-
-  default:
-    PrintFatalError("unknown OpKind!");
-  }
-  return s;
-}
-
-static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
-  unsigned mod = proto[0];
-
-  if (mod == 'v' || mod == 'f' || mod == 'F')
-    mod = proto[1];
-
-  bool quad = false;
-  bool poly = false;
-  bool usgn = false;
-  bool scal = false;
-  bool cnst = false;
-  bool pntr = false;
-
-  // Base type to get the type string for.
-  char type = ClassifyType(typestr, quad, poly, usgn);
-
-  // Based on the modifying character, change the type and width if necessary.
-  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
-
-  NeonTypeFlags::EltType ET;
-  switch (type) {
-    case 'c':
-      ET = poly ? NeonTypeFlags::Poly8 : NeonTypeFlags::Int8;
-      break;
-    case 's':
-      ET = poly ? NeonTypeFlags::Poly16 : NeonTypeFlags::Int16;
-      break;
-    case 'i':
-      ET = NeonTypeFlags::Int32;
-      break;
-    case 'l':
-      ET = poly ? NeonTypeFlags::Poly64 : NeonTypeFlags::Int64;
-      break;
-    case 'k':
-      ET = NeonTypeFlags::Poly128;
-      break;
-    case 'h':
-      ET = NeonTypeFlags::Float16;
-      break;
-    case 'f':
-      ET = NeonTypeFlags::Float32;
-      break;
-    case 'd':
-      ET = NeonTypeFlags::Float64;
-      break;
-    default:
-      PrintFatalError("unhandled type!");
-  }
-  NeonTypeFlags Flags(ET, usgn, quad && proto[1] != 'g');
-  return Flags.getFlags();
 }
 
 // We don't check 'a' in this function, because for builtin function the
 // argument matching to 'a' uses a vector type splatted from a scalar type.
-static bool ProtoHasScalar(const std::string proto)
-{
-  return (proto.find('s') != std::string::npos
-          || proto.find('z') != std::string::npos
-          || proto.find('r') != std::string::npos
-          || proto.find('b') != std::string::npos
-          || proto.find('$') != std::string::npos
-          || proto.find('y') != std::string::npos
-          || proto.find('o') != std::string::npos);
+bool Intrinsic::protoHasScalar() {
+  return (Proto.find('s') != std::string::npos ||
+          Proto.find('z') != std::string::npos ||
+          Proto.find('r') != std::string::npos ||
+          Proto.find('b') != std::string::npos ||
+          Proto.find('$') != std::string::npos ||
+          Proto.find('y') != std::string::npos ||
+          Proto.find('o') != std::string::npos);
 }
 
-// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)
-static std::string GenBuiltin(const std::string &name, const std::string &proto,
-                              StringRef typestr, ClassKind ck) {
-  std::string s;
+void Intrinsic::emitBodyAsBuiltinCall() {
+  std::string S;
 
   // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit
   // sret-like argument.
-  bool sret = IsMultiVecProto(proto[0]);
+  bool SRet = getReturnType().getNumVectors() >= 2;
 
-  bool define = UseMacro(proto, typestr);
-
-  // Check if the prototype has a scalar operand with the type of the vector
-  // elements.  If not, bitcasting the args will take care of arg checking.
-  // The actual signedness etc. will be taken care of with special enums.
-  if (!ProtoHasScalar(proto))
-    ck = ClassB;
-
-  if (proto[0] != 'v') {
-    std::string ts = TypeString(proto[0], typestr);
-
-    if (define) {
-      if (sret)
-        s += ts + " r; ";
-      else
-        s += "(" + ts + ")";
-    } else if (sret) {
-      s += ts + " r; ";
-    } else {
-      s += "return (" + ts + ")";
-    }
-  }
-
-  bool splat = proto.find('a') != std::string::npos;
-
-  s += "__builtin_neon_";
-  if (splat) {
+  StringRef N = Name;
+  if (hasSplat()) {
     // Call the non-splat builtin: chop off the "_n" suffix from the name.
-    std::string vname(name, 0, name.size()-2);
-    s += MangleName(vname, typestr, ck);
-  } else {
-    s += MangleName(name, typestr, ck);
+    assert(N.endswith("_n"));
+    N = N.drop_back(2);
   }
-  s += "(";
 
-  // Pass the address of the return variable as the first argument to sret-like
-  // builtins.
-  if (sret)
-    s += "&r, ";
+  ClassKind LocalCK = CK;
+  if (!protoHasScalar())
+    LocalCK = ClassB;
 
-  char arg = 'a';
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    std::string args = std::string(&arg, 1);
+  if (!getReturnType().isVoid() && !SRet)
+    S += "(" + RetVar.getType().str() + ") ";
 
-    // Use the local temporaries instead of the macro arguments.
-    args = "__" + args;
+  S += "__builtin_neon_" + mangleName(N, LocalCK) + "(";
 
-    bool argQuad = false;
-    bool argPoly = false;
-    bool argUsgn = false;
-    bool argScalar = false;
-    bool dummy = false;
-    char argType = ClassifyType(typestr, argQuad, argPoly, argUsgn);
-    argType = ModType(proto[i], argType, argQuad, argPoly, argUsgn, argScalar,
-                      dummy, dummy);
+  if (SRet)
+    S += "&" + RetVar.getName() + ", ";
+
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    Variable &V = Variables["p" + utostr(I)];
+    Type T = V.getType();
 
     // Handle multiple-vector values specially, emitting each subvector as an
-    // argument to the __builtin.
-    unsigned NumOfVec = 0;
-    if (proto[i] >= '2' && proto[i] <= '4') {
-      NumOfVec = proto[i] - '0';
-    } else if (proto[i] >= 'B' && proto[i] <= 'D') {
-      NumOfVec = proto[i] - 'A' + 1;
-    }
-
-    if (NumOfVec > 0) {
+    // argument to the builtin.
+    if (T.getNumVectors() > 1) {
       // Check if an explicit cast is needed.
-      if (argType != 'c' || argPoly || argUsgn)
-        args = (argQuad ? "(int8x16_t)" : "(int8x8_t)") + args;
-
-      for (unsigned vi = 0, ve = NumOfVec; vi != ve; ++vi) {
-        s += args + ".val[" + utostr(vi) + "]";
-        if ((vi + 1) < ve)
-          s += ", ";
+      std::string Cast;
+      if (T.isChar() || T.isPoly() || !T.isSigned()) {
+        Type T2 = T;
+        T2.makeOneVector();
+        T2.makeInteger(8, /*Signed=*/true);
+        Cast = "(" + T2.str() + ")";
       }
-      if ((i + 1) < e)
-        s += ", ";
 
+      for (unsigned J = 0; J < T.getNumVectors(); ++J)
+        S += Cast + V.getName() + ".val[" + utostr(J) + "], ";
       continue;
     }
 
-    if (splat && (i + 1) == e)
-      args = Duplicate(GetNumElements(typestr, argQuad), typestr, args);
+    std::string Arg;
+    Type CastToType = T;
+    if (hasSplat() && I == getSplatIdx()) {
+      Arg = "(" + BaseType.str() + ") {";
+      for (unsigned J = 0; J < BaseType.getNumElements(); ++J) {
+        if (J != 0)
+          Arg += ", ";
+        Arg += V.getName();
+      }
+      Arg += "}";
 
-    // Check if an explicit cast is needed.
-    if ((splat || !argScalar) &&
-        ((ck == ClassB && argType != 'c') || argPoly || argUsgn)) {
-      std::string argTypeStr = "c";
-      if (ck != ClassB)
-        argTypeStr = argType;
-      if (argQuad)
-        argTypeStr = "Q" + argTypeStr;
-      args = "(" + TypeString('d', argTypeStr) + ")" + args;
+      CastToType = BaseType;
+    } else {
+      Arg = V.getName();
     }
 
-    s += args;
-    if ((i + 1) < e)
-      s += ", ";
+    // Check if an explicit cast is needed.
+    if (CastToType.isVector()) {
+      CastToType.makeInteger(8, true);
+      Arg = "(" + CastToType.str() + ")" + Arg;
+    }
+
+    S += Arg + ", ";
   }
 
   // Extra constant integer to hold type class enum for this function, e.g. s8
-  if (ck == ClassB)
-    s += ", " + utostr(GetNeonEnum(proto, typestr));
+  if (getClassKind(true) == ClassB) {
+    Type ThisTy = getReturnType();
+    if (Proto[0] == 'v' || Proto[0] == 'f' || Proto[0] == 'F')
+      ThisTy = getParamType(0);
+    if (ThisTy.isPointer())
+      ThisTy = getParamType(1);
 
-  s += ");";
-
-  if (proto[0] != 'v' && sret) {
-    if (define)
-      s += " r;";
-    else
-      s += " return r;";
+    S += utostr(ThisTy.getNeonEnum());
+  } else {
+    // Remove extraneous ", ".
+    S.pop_back();
+    S.pop_back();
   }
-  return s;
+  S += ");";
+
+  std::string RetExpr;
+  if (!SRet && !RetVar.getType().isVoid())
+    RetExpr = RetVar.getName() + " = ";
+
+  OS << "  " << RetExpr << S;
+  emitNewLine();
 }
 
-static std::string GenBuiltinDef(const std::string &name,
-                                 const std::string &proto,
-                                 StringRef typestr, ClassKind ck) {
-  std::string s("BUILTIN(__builtin_neon_");
+void Intrinsic::emitBody(StringRef CallPrefix) {
+  std::vector<std::string> Lines;
 
-  // If all types are the same size, bitcasting the args will take care
-  // of arg checking.  The actual signedness etc. will be taken care of with
-  // special enums.
-  if (!ProtoHasScalar(proto))
-    ck = ClassB;
+  assert(RetVar.getType() == Types[0]);
+  // Create a return variable, if we're not void.
+  if (!RetVar.getType().isVoid()) {
+    OS << "  " << RetVar.getType().str() << " " << RetVar.getName() << ";";
+    emitNewLine();
+  }
 
-  s += MangleName(name, typestr, ck);
-  s += ", \"";
+  if (!Body || Body->getValues().size() == 0) {
+    // Nothing specific to output - must output a builtin.
+    emitBodyAsBuiltinCall();
+    return;
+  }
 
-  for (unsigned i = 0, e = proto.size(); i != e; ++i)
-    s += BuiltinTypeString(proto[i], typestr, ck, i == 0);
+  // We have a list of "things to output". The last should be returned.
+  for (auto *I : Body->getValues()) {
+    if (StringInit *SI = dyn_cast<StringInit>(I)) {
+      Lines.push_back(replaceParamsIn(SI->getAsString()));
+    } else if (DagInit *DI = dyn_cast<DagInit>(I)) {
+      DagEmitter DE(*this, CallPrefix);
+      Lines.push_back(DE.emitDag(DI).second + ";");
+    }
+  }
 
-  // Extra constant integer to hold type class enum for this function, e.g. s8
-  if (ck == ClassB)
-    s += "i";
+  assert(Lines.size() && "Empty def?");
+  if (!RetVar.getType().isVoid())
+    Lines.back().insert(0, RetVar.getName() + " = ");
 
-  s += "\", \"n\")";
-  return s;
+  for (auto &L : Lines) {
+    OS << "  " << L;
+    emitNewLine();
+  }
 }
 
-static std::string GenIntrinsic(const std::string &name,
-                                const std::string &proto,
-                                StringRef outTypeStr, StringRef inTypeStr,
-                                OpKind kind, ClassKind classKind) {
-  assert(!proto.empty() && "");
-  bool define = UseMacro(proto, outTypeStr) && kind != OpUnavailable;
-  std::string s;
-
-  // static always inline + return type
-  if (define)
-    s += "#define ";
+void Intrinsic::emitReturn() {
+  if (RetVar.getType().isVoid())
+    return;
+  if (UseMacro)
+    OS << "  " << RetVar.getName() << ";";
   else
-    s += "__ai " + TypeString(proto[0], outTypeStr) + " ";
+    OS << "  return " << RetVar.getName() << ";";
+  emitNewLine();
+}
 
-  // Function name with type suffix
-  std::string mangledName = MangleName(name, outTypeStr, ClassS);
-  if (outTypeStr != inTypeStr) {
-    // If the input type is different (e.g., for vreinterpret), append a suffix
-    // for the input type.  String off a "Q" (quad) prefix so that MangleName
-    // does not insert another "q" in the name.
-    unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0);
-    StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff);
-    mangledName = MangleName(mangledName, inTypeNoQuad, ClassS);
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDag(DagInit *DI) {
+  // At this point we should only be seeing a def.
+  DefInit *DefI = cast<DefInit>(DI->getOperator());
+  std::string Op = DefI->getAsString();
+
+  if (Op == "cast" || Op == "bitcast")
+    return emitDagCast(DI, Op == "bitcast");
+  if (Op == "shuffle")
+    return emitDagShuffle(DI);
+  if (Op == "dup")
+    return emitDagDup(DI);
+  if (Op == "splat")
+    return emitDagSplat(DI);
+  if (Op == "save_temp")
+    return emitDagSaveTemp(DI);
+  if (Op == "op")
+    return emitDagOp(DI);
+  if (Op == "call")
+    return emitDagCall(DI);
+  if (Op == "name_replace")
+    return emitDagNameReplace(DI);
+  if (Op == "literal")
+    return emitDagLiteral(DI);
+  assert_with_loc(false, "Unknown operation!");
+  return std::make_pair(Type::getVoid(), "");
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagOp(DagInit *DI) {
+  std::string Op = cast<StringInit>(DI->getArg(0))->getAsUnquotedString();
+  if (DI->getNumArgs() == 2) {
+    // Unary op.
+    std::pair<Type, std::string> R =
+        emitDagArg(DI->getArg(1), DI->getArgName(1));
+    return std::make_pair(R.first, Op + R.second);
+  } else {
+    assert(DI->getNumArgs() == 3 && "Can only handle unary and binary ops!");
+    std::pair<Type, std::string> R1 =
+        emitDagArg(DI->getArg(1), DI->getArgName(1));
+    std::pair<Type, std::string> R2 =
+        emitDagArg(DI->getArg(2), DI->getArgName(2));
+    assert_with_loc(R1.first == R2.first, "Argument type mismatch!");
+    return std::make_pair(R1.first, R1.second + " " + Op + " " + R2.second);
   }
-  s += mangledName;
+}
 
-  // Function arguments
-  s += GenArgs(proto, inTypeStr, name);
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCall(DagInit *DI) {
+  std::vector<Type> Types;
+  std::vector<std::string> Values;
+  for (unsigned I = 0; I < DI->getNumArgs() - 1; ++I) {
+    std::pair<Type, std::string> R =
+        emitDagArg(DI->getArg(I + 1), DI->getArgName(I + 1));
+    Types.push_back(R.first);
+    Values.push_back(R.second);
+  }
 
-  // Definition.
-  if (define) {
-    s += " __extension__ ({ \\\n  ";
-    s += GenMacroLocals(proto, inTypeStr, name);
-  } else if (kind == OpUnavailable) {
-    s += " __attribute__((unavailable));\n";
-    return s;
-  } else
-    s += " {\n  ";
-
-  if (kind != OpNone)
-    s += GenOpString(name, kind, proto, outTypeStr);
+  // Look up the called intrinsic.
+  std::string N;
+  if (StringInit *SI = dyn_cast<StringInit>(DI->getArg(0)))
+    N = SI->getAsUnquotedString();
   else
-    s += GenBuiltin(name, proto, outTypeStr, classKind);
-  if (define)
-    s += " })";
-  else
-    s += " }";
-  s += "\n";
-  return s;
+    N = emitDagArg(DI->getArg(0), "").second;
+  Intrinsic *Callee = Intr.Emitter.getIntrinsic(N, Types);
+  assert(Callee && "getIntrinsic should not return us nullptr!");
+
+  // Make sure the callee is known as an early def.
+  Callee->setNeededEarly();
+  Intr.Dependencies.insert(Callee);
+
+  // Now create the call itself.
+  std::string S = CallPrefix.str() + Callee->getMangledName(true) + "(";
+  for (unsigned I = 0; I < DI->getNumArgs() - 1; ++I) {
+    if (I != 0)
+      S += ", ";
+    S += Values[I];
+  }
+  S += ")";
+
+  return std::make_pair(Callee->getReturnType(), S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCast(DagInit *DI,
+                                                                bool IsBitCast){
+  // (cast MOD* VAL) -> cast VAL to type given by MOD.
+  std::pair<Type, std::string> R = emitDagArg(
+      DI->getArg(DI->getNumArgs() - 1), DI->getArgName(DI->getNumArgs() - 1));
+  Type castToType = R.first;
+  for (unsigned ArgIdx = 0; ArgIdx < DI->getNumArgs() - 1; ++ArgIdx) {
+
+    // MOD can take several forms:
+    //   1. $X - take the type of parameter / variable X.
+    //   2. The value "R" - take the type of the return type.
+    //   3. a type string
+    //   4. The value "U" or "S" to switch the signedness.
+    //   5. The value "H" or "D" to half or double the bitwidth.
+    //   6. The value "8" to convert to 8-bit (signed) integer lanes.
+    if (DI->getArgName(ArgIdx).size()) {
+      assert_with_loc(Intr.Variables.find(DI->getArgName(ArgIdx)) !=
+                      Intr.Variables.end(),
+                      "Variable not found");
+      castToType = Intr.Variables[DI->getArgName(ArgIdx)].getType();
+    } else {
+      StringInit *SI = dyn_cast<StringInit>(DI->getArg(ArgIdx));
+      assert_with_loc(SI, "Expected string type or $Name for cast type");
+
+      if (SI->getAsUnquotedString() == "R") {
+        castToType = Intr.getReturnType();
+      } else if (SI->getAsUnquotedString() == "U") {
+        castToType.makeUnsigned();
+      } else if (SI->getAsUnquotedString() == "S") {
+        castToType.makeSigned();
+      } else if (SI->getAsUnquotedString() == "H") {
+        castToType.halveLanes();
+      } else if (SI->getAsUnquotedString() == "D") {
+        castToType.doubleLanes();
+      } else if (SI->getAsUnquotedString() == "8") {
+        castToType.makeInteger(8, true);
+      } else {
+        castToType = Type::fromTypedefName(SI->getAsUnquotedString());
+        assert_with_loc(!castToType.isVoid(), "Unknown typedef");
+      }
+    }
+  }
+
+  std::string S;
+  if (IsBitCast) {
+    // Emit a reinterpret cast. The second operand must be an lvalue, so create
+    // a temporary.
+    std::string N = "reint";
+    unsigned I = 0;
+    while (Intr.Variables.find(N) != Intr.Variables.end())
+      N = "reint" + utostr(++I);
+    Intr.Variables[N] = Variable(R.first, N + Intr.VariablePostfix);
+
+    Intr.OS << R.first.str() << " " << Intr.Variables[N].getName() << " = "
+            << R.second << ";";
+    Intr.emitNewLine();
+
+    S = "*(" + castToType.str() + " *) &" + Intr.Variables[N].getName() + "";
+  } else {
+    // Emit a normal (static) cast.
+    S = "(" + castToType.str() + ")(" + R.second + ")";
+  }
+
+  return std::make_pair(castToType, S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){
+  // See the documentation in arm_neon.td for a description of these operators.
+  class LowHalf : public SetTheory::Operator {
+  public:
+    virtual void anchor() {}
+    virtual ~LowHalf() {}
+    virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
+                       ArrayRef<SMLoc> Loc) {
+      SetTheory::RecSet Elts2;
+      ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts2, Loc);
+      Elts.insert(Elts2.begin(), Elts2.begin() + (Elts2.size() / 2));
+    }
+  };
+  class HighHalf : public SetTheory::Operator {
+  public:
+    virtual void anchor() {}
+    virtual ~HighHalf() {}
+    virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
+                       ArrayRef<SMLoc> Loc) {
+      SetTheory::RecSet Elts2;
+      ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts2, Loc);
+      Elts.insert(Elts2.begin() + (Elts2.size() / 2), Elts2.end());
+    }
+  };
+  class Rev : public SetTheory::Operator {
+    unsigned ElementSize;
+
+  public:
+    Rev(unsigned ElementSize) : ElementSize(ElementSize) {}
+    virtual void anchor() {}
+    virtual ~Rev() {}
+    virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
+                       ArrayRef<SMLoc> Loc) {
+      SetTheory::RecSet Elts2;
+      ST.evaluate(Expr->arg_begin() + 1, Expr->arg_end(), Elts2, Loc);
+
+      int64_t VectorSize = cast<IntInit>(Expr->getArg(0))->getValue();
+      VectorSize /= ElementSize;
+
+      std::vector<Record *> Revved;
+      for (unsigned VI = 0; VI < Elts2.size(); VI += VectorSize) {
+        for (int LI = VectorSize - 1; LI >= 0; --LI) {
+          Revved.push_back(Elts2[VI + LI]);
+        }
+      }
+
+      Elts.insert(Revved.begin(), Revved.end());
+    }
+  };
+  class MaskExpander : public SetTheory::Expander {
+    unsigned N;
+
+  public:
+    MaskExpander(unsigned N) : N(N) {}
+    virtual void anchor() {}
+    virtual ~MaskExpander() {}
+    virtual void expand(SetTheory &ST, Record *R, SetTheory::RecSet &Elts) {
+      unsigned Addend = 0;
+      if (R->getName() == "mask0")
+        Addend = 0;
+      else if (R->getName() == "mask1")
+        Addend = N;
+      else
+        return;
+      for (unsigned I = 0; I < N; ++I)
+        Elts.insert(R->getRecords().getDef("sv" + utostr(I + Addend)));
+    }
+  };
+
+  // (shuffle arg1, arg2, sequence)
+  std::pair<Type, std::string> Arg1 =
+      emitDagArg(DI->getArg(0), DI->getArgName(0));
+  std::pair<Type, std::string> Arg2 =
+      emitDagArg(DI->getArg(1), DI->getArgName(1));
+  assert_with_loc(Arg1.first == Arg2.first,
+                  "Different types in arguments to shuffle!");
+
+  SetTheory ST;
+  LowHalf LH;
+  HighHalf HH;
+  MaskExpander ME(Arg1.first.getNumElements());
+  Rev R(Arg1.first.getElementSizeInBits());
+  SetTheory::RecSet Elts;
+  ST.addOperator("lowhalf", &LH);
+  ST.addOperator("highhalf", &HH);
+  ST.addOperator("rev", &R);
+  ST.addExpander("MaskExpand", &ME);
+  ST.evaluate(DI->getArg(2), Elts, ArrayRef<SMLoc>());
+
+  std::string S = "__builtin_shufflevector(" + Arg1.second + ", " + Arg2.second;
+  for (auto &E : Elts) {
+    StringRef Name = E->getName();
+    assert_with_loc(Name.startswith("sv"),
+                    "Incorrect element kind in shuffle mask!");
+    S += ", " + Name.drop_front(2).str();
+  }
+  S += ")";
+
+  // Recalculate the return type - the shuffle may have halved or doubled it.
+  Type T(Arg1.first);
+  if (Elts.size() > T.getNumElements()) {
+    assert_with_loc(
+        Elts.size() == T.getNumElements() * 2,
+        "Can only double or half the number of elements in a shuffle!");
+    T.doubleLanes();
+  } else if (Elts.size() < T.getNumElements()) {
+    assert_with_loc(
+        Elts.size() == T.getNumElements() / 2,
+        "Can only double or half the number of elements in a shuffle!");
+    T.halveLanes();
+  }
+
+  return std::make_pair(T, S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDup(DagInit *DI) {
+  assert_with_loc(DI->getNumArgs() == 1, "dup() expects one argument");
+  std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), DI->getArgName(0));
+  assert_with_loc(A.first.isScalar(), "dup() expects a scalar argument");
+
+  Type T = Intr.getBaseType();
+  assert_with_loc(T.isVector(), "dup() used but default type is scalar!");
+  std::string S = "(" + T.str() + ") {";
+  for (unsigned I = 0; I < T.getNumElements(); ++I) {
+    if (I != 0)
+      S += ", ";
+    S += A.second;
+  }
+  S += "}";
+
+  return std::make_pair(T, S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSplat(DagInit *DI) {
+  assert_with_loc(DI->getNumArgs() == 2, "splat() expects two arguments");
+  std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), DI->getArgName(0));
+  std::pair<Type, std::string> B = emitDagArg(DI->getArg(1), DI->getArgName(1));
+
+  assert_with_loc(B.first.isScalar(),
+                  "splat() requires a scalar int as the second argument");
+
+  std::string S = "__builtin_shufflevector(" + A.second + ", " + A.second;
+  for (unsigned I = 0; I < Intr.getBaseType().getNumElements(); ++I) {
+    S += ", " + B.second;
+  }
+  S += ")";
+
+  return std::make_pair(Intr.getBaseType(), S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSaveTemp(DagInit *DI) {
+  assert_with_loc(DI->getNumArgs() == 2, "save_temp() expects two arguments");
+  std::pair<Type, std::string> A = emitDagArg(DI->getArg(1), DI->getArgName(1));
+
+  assert_with_loc(!A.first.isVoid(),
+                  "Argument to save_temp() must have non-void type!");
+
+  std::string N = DI->getArgName(0);
+  assert_with_loc(N.size(), "save_temp() expects a name as the first argument");
+
+  assert_with_loc(Intr.Variables.find(N) == Intr.Variables.end(),
+                  "Variable already defined!");
+  Intr.Variables[N] = Variable(A.first, N + Intr.VariablePostfix);
+
+  std::string S =
+      A.first.str() + " " + Intr.Variables[N].getName() + " = " + A.second;
+
+  return std::make_pair(Type::getVoid(), S);
+}
+
+std::pair<Type, std::string>
+Intrinsic::DagEmitter::emitDagNameReplace(DagInit *DI) {
+  std::string S = Intr.Name;
+
+  assert_with_loc(DI->getNumArgs() == 2, "name_replace requires 2 arguments!");
+  std::string ToReplace = cast<StringInit>(DI->getArg(0))->getAsUnquotedString();
+  std::string ReplaceWith = cast<StringInit>(DI->getArg(1))->getAsUnquotedString();
+
+  size_t Idx = S.find(ToReplace);
+
+  assert_with_loc(Idx != std::string::npos, "name should contain '" + ToReplace + "'!");
+  S.replace(Idx, ToReplace.size(), ReplaceWith);
+
+  return std::make_pair(Type::getVoid(), S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagLiteral(DagInit *DI){
+  std::string Ty = cast<StringInit>(DI->getArg(0))->getAsUnquotedString();
+  std::string Value = cast<StringInit>(DI->getArg(1))->getAsUnquotedString();
+  return std::make_pair(Type::fromTypedefName(Ty), Value);
+}
+
+std::pair<Type, std::string>
+Intrinsic::DagEmitter::emitDagArg(Init *Arg, std::string ArgName) {
+  if (ArgName.size()) {
+    assert_with_loc(!Arg->isComplete(),
+                    "Arguments must either be DAGs or names, not both!");
+    assert_with_loc(Intr.Variables.find(ArgName) != Intr.Variables.end(),
+                    "Variable not defined!");
+    Variable &V = Intr.Variables[ArgName];
+    return std::make_pair(V.getType(), V.getName());
+  }
+
+  assert(Arg && "Neither ArgName nor Arg?!");
+  DagInit *DI = dyn_cast<DagInit>(Arg);
+  assert_with_loc(DI, "Arguments must either be DAGs or names!");
+
+  return emitDag(DI);
+}
+
+std::string Intrinsic::generate() {
+  // Little endian intrinsics are simple and don't require any argument
+  // swapping.
+  OS << "#ifdef __LITTLE_ENDIAN__\n";
+
+  generateImpl(false, "", "");
+
+  OS << "#else\n";
+
+  // Big endian intrinsics are more complex. The user intended these
+  // intrinsics to operate on a vector "as-if" loaded by (V)LDR,
+  // but we load as-if (V)LD1. So we should swap all arguments and
+  // swap the return value too.
+  //
+  // If we call sub-intrinsics, we should call a version that does
+  // not re-swap the arguments!
+  generateImpl(true, "", "__noswap_");
+
+  // If we're needed early, create a non-swapping variant for
+  // big-endian.
+  if (NeededEarly) {
+    generateImpl(false, "__noswap_", "__noswap_");
+  }
+  OS << "#endif\n\n";
+
+  return OS.str();
+}
+
+void Intrinsic::generateImpl(bool ReverseArguments,
+                             StringRef NamePrefix, StringRef CallPrefix) {
+  CurrentRecord = R;
+
+  // If we call a macro, our local variables may be corrupted due to
+  // lack of proper lexical scoping. So, add a globally unique postfix
+  // to every variable.
+  //
+  // indexBody() should have set up the Dependencies set by now.
+  for (auto *I : Dependencies)
+    if (I->UseMacro) {
+      VariablePostfix = "_" + utostr(Emitter.getUniqueNumber());
+      break;
+    }
+
+  initVariables();
+
+  emitPrototype(NamePrefix);
+
+  if (IsUnavailable) {
+    OS << " __attribute__((unavailable));";
+  } else {
+    emitOpeningBrace();
+    emitShadowedArgs();
+    if (ReverseArguments)
+      emitArgumentReversal();
+    emitBody(CallPrefix);
+    if (ReverseArguments)
+      emitReturnReversal();
+    emitReturn();
+    emitClosingBrace();
+  }
+  OS << "\n";
+
+  CurrentRecord = nullptr;
+}
+
+void Intrinsic::indexBody() {
+  CurrentRecord = R;
+
+  initVariables();
+  emitBody("");
+  OS.str("");
+
+  CurrentRecord = nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// NeonEmitter implementation
+//===----------------------------------------------------------------------===//
+
+Intrinsic *NeonEmitter::getIntrinsic(StringRef Name, ArrayRef<Type> Types) {
+  // First, look up the name in the intrinsic map.
+  assert_with_loc(IntrinsicMap.find(Name.str()) != IntrinsicMap.end(),
+                  ("Intrinsic '" + Name + "' not found!").str());
+  std::vector<Intrinsic *> &V = IntrinsicMap[Name.str()];
+  std::vector<Intrinsic *> GoodVec;
+
+  // Create a string to print if we end up failing.
+  std::string ErrMsg = "looking up intrinsic '" + Name.str() + "(";
+  for (unsigned I = 0; I < Types.size(); ++I) {
+    if (I != 0)
+      ErrMsg += ", ";
+    ErrMsg += Types[I].str();
+  }
+  ErrMsg += ")'\n";
+  ErrMsg += "Available overloads:\n";
+
+  // Now, look through each intrinsic implementation and see if the types are
+  // compatible.
+  for (auto *I : V) {
+    ErrMsg += "  - " + I->getReturnType().str() + " " + I->getMangledName();
+    ErrMsg += "(";
+    for (unsigned A = 0; A < I->getNumParams(); ++A) {
+      if (A != 0)
+        ErrMsg += ", ";
+      ErrMsg += I->getParamType(A).str();
+    }
+    ErrMsg += ")\n";
+
+    if (I->getNumParams() != Types.size())
+      continue;
+
+    bool Good = true;
+    for (unsigned Arg = 0; Arg < Types.size(); ++Arg) {
+      if (I->getParamType(Arg) != Types[Arg]) {
+        Good = false;
+        break;
+      }
+    }
+    if (Good)
+      GoodVec.push_back(I);
+  }
+
+  assert_with_loc(GoodVec.size() > 0,
+                  "No compatible intrinsic found - " + ErrMsg);
+  assert_with_loc(GoodVec.size() == 1, "Multiple overloads found - " + ErrMsg);
+
+  return GoodVec.front();
+}
+
+void NeonEmitter::createIntrinsic(Record *R,
+                                  SmallVectorImpl<Intrinsic *> &Out) {
+  std::string Name = R->getValueAsString("Name");
+  std::string Proto = R->getValueAsString("Prototype");
+  std::string Types = R->getValueAsString("Types");
+  Record *OperationRec = R->getValueAsDef("Operation");
+  bool CartesianProductOfTypes = R->getValueAsBit("CartesianProductOfTypes");
+  bool BigEndianSafe  = R->getValueAsBit("BigEndianSafe");
+  std::string Guard = R->getValueAsString("ArchGuard");
+  bool IsUnavailable = OperationRec->getValueAsBit("Unavailable");
+
+  // Set the global current record. This allows assert_with_loc to produce
+  // decent location information even when highly nested.
+  CurrentRecord = R;
+
+  ListInit *Body = OperationRec->getValueAsListInit("Ops");
+
+  std::vector<TypeSpec> TypeSpecs = TypeSpec::fromTypeSpecs(Types);
+
+  ClassKind CK = ClassNone;
+  if (R->getSuperClasses().size() >= 2)
+    CK = ClassMap[R->getSuperClasses()[1]];
+
+  std::vector<std::pair<TypeSpec, TypeSpec>> NewTypeSpecs;
+  for (auto TS : TypeSpecs) {
+    if (CartesianProductOfTypes) {
+      Type DefaultT(TS, 'd');
+      for (auto SrcTS : TypeSpecs) {
+        Type DefaultSrcT(SrcTS, 'd');
+        if (TS == SrcTS ||
+            DefaultSrcT.getSizeInBits() != DefaultT.getSizeInBits())
+          continue;
+        NewTypeSpecs.push_back(std::make_pair(TS, SrcTS));
+      }
+    } else {
+      NewTypeSpecs.push_back(std::make_pair(TS, TS));
+    }
+  }
+
+  std::sort(NewTypeSpecs.begin(), NewTypeSpecs.end());
+  std::unique(NewTypeSpecs.begin(), NewTypeSpecs.end());
+
+  for (auto &I : NewTypeSpecs) {
+    Intrinsic *IT = new Intrinsic(R, Name, Proto, I.first, I.second, CK, Body,
+                                  *this, Guard, IsUnavailable, BigEndianSafe);
+
+    IntrinsicMap[Name].push_back(IT);
+    Out.push_back(IT);
+  }
+
+  CurrentRecord = nullptr;
+}
+
+/// genBuiltinsDef: Generate the BuiltinsARM.def and  BuiltinsAArch64.def
+/// declaration of builtins, checking for unique builtin declarations.
+void NeonEmitter::genBuiltinsDef(raw_ostream &OS,
+                                 SmallVectorImpl<Intrinsic *> &Defs) {
+  OS << "#ifdef GET_NEON_BUILTINS\n";
+
+  // We only want to emit a builtin once, and we want to emit them in
+  // alphabetical order, so use a std::set.
+  std::set<std::string> Builtins;
+
+  for (auto *Def : Defs) {
+    if (Def->hasBody())
+      continue;
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Def->hasSplat())
+      continue;
+
+    std::string S = "BUILTIN(__builtin_neon_" + Def->getMangledName() + ", \"";
+
+    S += Def->getBuiltinTypeStr();
+    S += "\", \"n\")";
+
+    Builtins.insert(S);
+  }
+
+  for (auto &S : Builtins)
+    OS << S << "\n";
+  OS << "#endif\n\n";
+}
+
+/// Generate the ARM and AArch64 overloaded type checking code for
+/// SemaChecking.cpp, checking for unique builtin declarations.
+void NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS,
+                                           SmallVectorImpl<Intrinsic *> &Defs) {
+  OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n";
+
+  // We record each overload check line before emitting because subsequent Inst
+  // definitions may extend the number of permitted types (i.e. augment the
+  // Mask). Use std::map to avoid sorting the table by hash number.
+  struct OverloadInfo {
+    uint64_t Mask;
+    int PtrArgNum;
+    bool HasConstPtr;
+    OverloadInfo() : Mask(0ULL), PtrArgNum(0), HasConstPtr(false) {}
+  };
+  std::map<std::string, OverloadInfo> OverloadMap;
+
+  for (auto *Def : Defs) {
+    // If the def has a body (that is, it has Operation DAGs), it won't call
+    // __builtin_neon_* so we don't need to generate a definition for it.
+    if (Def->hasBody())
+      continue;
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Def->hasSplat())
+      continue;
+    // Functions which have a scalar argument cannot be overloaded, no need to
+    // check them if we are emitting the type checking code.
+    if (Def->protoHasScalar())
+      continue;
+
+    uint64_t Mask = 0ULL;
+    Type Ty = Def->getReturnType();
+    if (Def->getProto()[0] == 'v' || Def->getProto()[0] == 'f' ||
+        Def->getProto()[0] == 'F')
+      Ty = Def->getParamType(0);
+    if (Ty.isPointer())
+      Ty = Def->getParamType(1);
+
+    Mask |= 1ULL << Ty.getNeonEnum();
+
+    // Check if the function has a pointer or const pointer argument.
+    std::string Proto = Def->getProto();
+    int PtrArgNum = -1;
+    bool HasConstPtr = false;
+    for (unsigned I = 0; I < Def->getNumParams(); ++I) {
+      char ArgType = Proto[I + 1];
+      if (ArgType == 'c') {
+        HasConstPtr = true;
+        PtrArgNum = I;
+        break;
+      }
+      if (ArgType == 'p') {
+        PtrArgNum = I;
+        break;
+      }
+    }
+    // For sret builtins, adjust the pointer argument index.
+    if (PtrArgNum >= 0 && Def->getReturnType().getNumVectors() > 1)
+      PtrArgNum += 1;
+
+    std::string Name = Def->getName();
+    // Omit type checking for the pointer arguments of vld1_lane, vld1_dup,
+    // and vst1_lane intrinsics.  Using a pointer to the vector element
+    // type with one of those operations causes codegen to select an aligned
+    // load/store instruction.  If you want an unaligned operation,
+    // the pointer argument needs to have less alignment than element type,
+    // so just accept any pointer type.
+    if (Name == "vld1_lane" || Name == "vld1_dup" || Name == "vst1_lane") {
+      PtrArgNum = -1;
+      HasConstPtr = false;
+    }
+
+    if (Mask) {
+      std::string Name = Def->getMangledName();
+      OverloadMap.insert(std::make_pair(Name, OverloadInfo()));
+      OverloadInfo &OI = OverloadMap[Name];
+      OI.Mask |= Mask;
+      OI.PtrArgNum |= PtrArgNum;
+      OI.HasConstPtr = HasConstPtr;
+    }
+  }
+
+  for (auto &I : OverloadMap) {
+    OverloadInfo &OI = I.second;
+
+    OS << "case NEON::BI__builtin_neon_" << I.first << ": ";
+    OS << "mask = 0x" << utohexstr(OI.Mask) << "ULL";
+    if (OI.PtrArgNum >= 0)
+      OS << "; PtrArgNum = " << OI.PtrArgNum;
+    if (OI.HasConstPtr)
+      OS << "; HasConstPtr = true";
+    OS << "; break;\n";
+  }
+  OS << "#endif\n\n";
+}
+
+void
+NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
+                                        SmallVectorImpl<Intrinsic *> &Defs) {
+  OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n";
+
+  std::set<std::string> Emitted;
+
+  for (auto *Def : Defs) {
+    if (Def->hasBody())
+      continue;
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Def->hasSplat())
+      continue;
+    // Functions which do not have an immediate do not ned to have range
+    // checking
+    // code emitted.
+    if (!Def->hasImmediate())
+      continue;
+    if (Emitted.find(Def->getMangledName()) != Emitted.end())
+      continue;
+
+    std::string LowerBound, UpperBound;
+
+    Record *R = Def->getRecord();
+    if (R->getValueAsBit("isVCVT_N")) {
+      // VCVT between floating- and fixed-point values takes an immediate
+      // in the range [1, 32) for f32 or [1, 64) for f64.
+      LowerBound = "1";
+      if (Def->getBaseType().getElementSizeInBits() == 32)
+        UpperBound = "31";
+      else
+        UpperBound = "63";
+    } else if (R->getValueAsBit("isScalarShift")) {
+      // Right shifts have an 'r' in the name, left shifts do not. Convert
+      // instructions have the same bounds and right shifts.
+      if (Def->getName().find('r') != std::string::npos ||
+          Def->getName().find("cvt") != std::string::npos)
+        LowerBound = "1";
+
+      UpperBound = utostr(Def->getReturnType().getElementSizeInBits() - 1);
+    } else if (R->getValueAsBit("isShift")) {
+      // Builtins which are overloaded by type will need to have thier upper
+      // bound computed at Sema time based on the type constant.
+
+      // Right shifts have an 'r' in the name, left shifts do not.
+      if (Def->getName().find('r') != std::string::npos)
+        LowerBound = "1";
+      UpperBound = "RFT(TV, true)";
+    } else if (Def->getClassKind(true) == ClassB) {
+      // ClassB intrinsics have a type (and hence lane number) that is only
+      // known at runtime.
+      if (R->getValueAsBit("isLaneQ"))
+        UpperBound = "RFT(TV, false, true)";
+      else
+        UpperBound = "RFT(TV, false, false)";
+    } else {
+      // The immediate generally refers to a lane in the preceding argument.
+      assert(Def->getImmediateIdx() > 0);
+      Type T = Def->getParamType(Def->getImmediateIdx() - 1);
+      UpperBound = utostr(T.getNumElements() - 1);
+    }
+
+    // Calculate the index of the immediate that should be range checked.
+    unsigned Idx = Def->getNumParams();
+    if (Def->hasImmediate())
+      Idx = Def->getGeneratedParamIdx(Def->getImmediateIdx());
+
+    OS << "case NEON::BI__builtin_neon_" << Def->getMangledName() << ": "
+       << "i = " << Idx << ";";
+    if (LowerBound.size())
+      OS << " l = " << LowerBound << ";";
+    if (UpperBound.size())
+      OS << " u = " << UpperBound << ";";
+    OS << " break;\n";
+
+    Emitted.insert(Def->getMangledName());
+  }
+
+  OS << "#endif\n\n";
+}
+
+/// runHeader - Emit a file with sections defining:
+/// 1. the NEON section of BuiltinsARM.def and BuiltinsAArch64.def.
+/// 2. the SemaChecking code for the type overload checking.
+/// 3. the SemaChecking code for validation of intrinsic immediate arguments.
+void NeonEmitter::runHeader(raw_ostream &OS) {
+  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
+
+  SmallVector<Intrinsic *, 128> Defs;
+  for (auto *R : RV)
+    createIntrinsic(R, Defs);
+
+  // Generate shared BuiltinsXXX.def
+  genBuiltinsDef(OS, Defs);
+
+  // Generate ARM overloaded type checking code for SemaChecking.cpp
+  genOverloadTypeCheckCode(OS, Defs);
+
+  // Generate ARM range checking code for shift/lane immediates.
+  genIntrinsicRangeCheckCode(OS, Defs);
 }
 
 /// run - Read the records in arm_neon.td and output arm_neon.h.  arm_neon.h
 /// is comprised of type definitions and function declarations.
 void NeonEmitter::run(raw_ostream &OS) {
-  OS <<
-    "/*===---- arm_neon.h - ARM Neon intrinsics ------------------------------"
-    "---===\n"
-    " *\n"
-    " * Permission is hereby granted, free of charge, to any person obtaining "
-    "a copy\n"
-    " * of this software and associated documentation files (the \"Software\"),"
-    " to deal\n"
-    " * in the Software without restriction, including without limitation the "
-    "rights\n"
-    " * to use, copy, modify, merge, publish, distribute, sublicense, "
-    "and/or sell\n"
-    " * copies of the Software, and to permit persons to whom the Software is\n"
-    " * furnished to do so, subject to the following conditions:\n"
-    " *\n"
-    " * The above copyright notice and this permission notice shall be "
-    "included in\n"
-    " * all copies or substantial portions of the Software.\n"
-    " *\n"
-    " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, "
-    "EXPRESS OR\n"
-    " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF "
-    "MERCHANTABILITY,\n"
-    " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT "
-    "SHALL THE\n"
-    " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR "
-    "OTHER\n"
-    " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, "
-    "ARISING FROM,\n"
-    " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER "
-    "DEALINGS IN\n"
-    " * THE SOFTWARE.\n"
-    " *\n"
-    " *===--------------------------------------------------------------------"
-    "---===\n"
-    " */\n\n";
+  OS << "/*===---- arm_neon.h - ARM Neon intrinsics "
+        "------------------------------"
+        "---===\n"
+        " *\n"
+        " * Permission is hereby granted, free of charge, to any person "
+        "obtaining "
+        "a copy\n"
+        " * of this software and associated documentation files (the "
+        "\"Software\"),"
+        " to deal\n"
+        " * in the Software without restriction, including without limitation "
+        "the "
+        "rights\n"
+        " * to use, copy, modify, merge, publish, distribute, sublicense, "
+        "and/or sell\n"
+        " * copies of the Software, and to permit persons to whom the Software "
+        "is\n"
+        " * furnished to do so, subject to the following conditions:\n"
+        " *\n"
+        " * The above copyright notice and this permission notice shall be "
+        "included in\n"
+        " * all copies or substantial portions of the Software.\n"
+        " *\n"
+        " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, "
+        "EXPRESS OR\n"
+        " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF "
+        "MERCHANTABILITY,\n"
+        " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT "
+        "SHALL THE\n"
+        " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR "
+        "OTHER\n"
+        " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, "
+        "ARISING FROM,\n"
+        " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER "
+        "DEALINGS IN\n"
+        " * THE SOFTWARE.\n"
+        " *\n"
+        " *===-----------------------------------------------------------------"
+        "---"
+        "---===\n"
+        " */\n\n";
 
   OS << "#ifndef __ARM_NEON_H\n";
   OS << "#define __ARM_NEON_H\n\n";
@@ -2654,765 +2258,132 @@
   // Emit Neon vector typedefs.
   std::string TypedefTypes(
       "cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQdPcQPcPsQPsPlQPl");
-  SmallVector<StringRef, 24> TDTypeVec;
-  ParseTypes(nullptr, TypedefTypes, TDTypeVec);
+  std::vector<TypeSpec> TDTypeVec = TypeSpec::fromTypeSpecs(TypedefTypes);
 
   // Emit vector typedefs.
-  bool isA64 = false;
-  bool preinsert;
-  bool postinsert;
-  for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
-    bool dummy, quad = false, poly = false;
-    char type = ClassifyType(TDTypeVec[i], quad, poly, dummy);
-    preinsert = false;
-    postinsert = false;
+  bool InIfdef = false;
+  for (auto &TS : TDTypeVec) {
+    bool IsA64 = false;
+    Type T(TS, 'd');
+    if (T.isDouble() || (T.isPoly() && T.isLong()))
+      IsA64 = true;
 
-    if (type == 'd' || (type == 'l' && poly)) {
-      preinsert = isA64? false: true;
-      isA64 = true;
-    } else {
-      postinsert = isA64? true: false;
-      isA64 = false;
-    }
-    if (postinsert)
+    if (InIfdef && !IsA64) {
       OS << "#endif\n";
-    if (preinsert)
+      InIfdef = false;
+    }
+    if (!InIfdef && IsA64) {
       OS << "#ifdef __aarch64__\n";
+      InIfdef = true;
+    }
 
-    if (poly)
+    if (T.isPoly())
       OS << "typedef __attribute__((neon_polyvector_type(";
     else
       OS << "typedef __attribute__((neon_vector_type(";
 
-    unsigned nElts = GetNumElements(TDTypeVec[i], quad);
-    OS << utostr(nElts) << "))) ";
-    if (nElts < 10)
-      OS << " ";
-
-    OS << TypeString('s', TDTypeVec[i]);
-    OS << " " << TypeString('d', TDTypeVec[i]) << ";\n";
-
+    Type T2 = T;
+    T2.makeScalar();
+    OS << utostr(T.getNumElements()) << "))) ";
+    OS << T2.str();
+    OS << " " << T.str() << ";\n";
   }
-  postinsert = isA64? true: false;
-  if (postinsert)
+  if (InIfdef)
     OS << "#endif\n";
   OS << "\n";
 
   // Emit struct typedefs.
-  isA64 = false;
-  for (unsigned vi = 2; vi != 5; ++vi) {
-    for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
-      bool dummy, quad = false, poly = false;
-      char type = ClassifyType(TDTypeVec[i], quad, poly, dummy);
-      preinsert = false;
-      postinsert = false;
+  InIfdef = false;
+  for (unsigned NumMembers = 2; NumMembers <= 4; ++NumMembers) {
+    for (auto &TS : TDTypeVec) {
+      bool IsA64 = false;
+      Type T(TS, 'd');
+      if (T.isDouble() || (T.isPoly() && T.isLong()))
+        IsA64 = true;
 
-      if (type == 'd' || (type == 'l' && poly)) {
-        preinsert = isA64? false: true;
-        isA64 = true;
-      } else {
-        postinsert = isA64? true: false;
-        isA64 = false;
-      }
-      if (postinsert)
+      if (InIfdef && !IsA64) {
         OS << "#endif\n";
-      if (preinsert)
+        InIfdef = false;
+      }
+      if (!InIfdef && IsA64) {
         OS << "#ifdef __aarch64__\n";
+        InIfdef = true;
+      }
 
-      std::string ts = TypeString('d', TDTypeVec[i]);
-      std::string vs = TypeString('0' + vi, TDTypeVec[i]);
-      OS << "typedef struct " << vs << " {\n";
-      OS << "  " << ts << " val";
-      OS << "[" << utostr(vi) << "]";
+      char M = '2' + (NumMembers - 2);
+      Type VT(TS, M);
+      OS << "typedef struct " << VT.str() << " {\n";
+      OS << "  " << T.str() << " val";
+      OS << "[" << utostr(NumMembers) << "]";
       OS << ";\n} ";
-      OS << vs << ";\n";
+      OS << VT.str() << ";\n";
       OS << "\n";
     }
   }
-  postinsert = isA64? true: false;
-  if (postinsert)
+  if (InIfdef)
     OS << "#endif\n";
   OS << "\n";
 
-  OS<<"#define __ai static inline __attribute__((__always_inline__, __nodebug__))\n\n";
+  OS << "#define __ai static inline __attribute__((__always_inline__, "
+        "__nodebug__))\n\n";
 
-  std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
+  SmallVector<Intrinsic *, 128> Defs;
+  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
+  for (auto *R : RV)
+    createIntrinsic(R, Defs);
 
-  StringMap<ClassKind> EmittedMap;
-  std::string CurrentGuard = "";
-  bool InGuard = false;
+  for (auto *I : Defs)
+    I->indexBody();
 
-  // Some intrinsics are used to express others. These need to be emitted near
-  // the beginning so that the declarations are present when needed. This is
-  // rather an ugly, arbitrary list, but probably simpler than actually tracking
-  // dependency info.
-  static const char *EarlyDefsArr[] =
-      { "VFMA",      "VQMOVN",    "VQMOVUN",  "VABD",    "VMOVL",
-        "VABDL",     "VGET_HIGH", "VCOMBINE", "VSHLL_N", "VMOVL_HIGH",
-        "VMULL",     "VMLAL_N",   "VMLSL_N",  "VMULL_N", "VMULL_P64",
-        "VQDMLAL_N", "VQDMLSL_N", "VQDMULL_N" };
-  ArrayRef<const char *> EarlyDefs(EarlyDefsArr);
+  std::stable_sort(
+      Defs.begin(), Defs.end(),
+      [](const Intrinsic *A, const Intrinsic *B) { return *A < *B; });
 
-  for (unsigned i = 0; i < EarlyDefs.size(); ++i) {
-    Record *R = Records.getDef(EarlyDefs[i]);
-    emitGuardedIntrinsic(OS, R, CurrentGuard, InGuard, EmittedMap);
+  // Only emit a def when its requirements have been met.
+  // FIXME: This loop could be made faster, but it's fast enough for now.
+  bool MadeProgress = true;
+  std::string InGuard = "";
+  while (!Defs.empty() && MadeProgress) {
+    MadeProgress = false;
+
+    for (SmallVector<Intrinsic *, 128>::iterator I = Defs.begin();
+         I != Defs.end(); /*No step*/) {
+      bool DependenciesSatisfied = true;
+      for (auto *II : (*I)->getDependencies()) {
+        if (std::find(Defs.begin(), Defs.end(), II) != Defs.end())
+          DependenciesSatisfied = false;
+      }
+      if (!DependenciesSatisfied) {
+        // Try the next one.
+        ++I;
+        continue;
+      }
+
+      // Emit #endif/#if pair if needed.
+      if ((*I)->getGuard() != InGuard) {
+        if (!InGuard.empty())
+          OS << "#endif\n";
+        InGuard = (*I)->getGuard();
+        if (!InGuard.empty())
+          OS << "#if " << InGuard << "\n";
+      }
+
+      // Actually generate the intrinsic code.
+      OS << (*I)->generate();
+
+      MadeProgress = true;
+      I = Defs.erase(I);
+    }
   }
+  assert(Defs.empty() && "Some requirements were not satisfied!");
+  if (!InGuard.empty())
+    OS << "#endif\n";
 
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-    if (std::find(EarlyDefs.begin(), EarlyDefs.end(), R->getName()) !=
-        EarlyDefs.end())
-      continue;
-
-    emitGuardedIntrinsic(OS, R, CurrentGuard, InGuard, EmittedMap);
-  }
-
-  if (InGuard)
-    OS << "#endif\n\n";
-
+  OS << "\n";
   OS << "#undef __ai\n\n";
   OS << "#endif /* __ARM_NEON_H */\n";
 }
 
-void NeonEmitter::emitGuardedIntrinsic(raw_ostream &OS, Record *R,
-                                       std::string &CurrentGuard, bool &InGuard,
-                                       StringMap<ClassKind> &EmittedMap) {
-
-  std::string NewGuard = R->getValueAsString("ArchGuard");
-  if (NewGuard != CurrentGuard) {
-    if (InGuard)
-      OS << "#endif\n\n";
-    if (NewGuard.size())
-      OS << "#if " << NewGuard << '\n';
-
-    CurrentGuard = NewGuard;
-    InGuard = NewGuard.size() != 0;
-  }
-
-  emitIntrinsic(OS, R, EmittedMap);
-}
-
-/// emitIntrinsic - Write out the arm_neon.h header file definitions for the
-/// intrinsics specified by record R checking for intrinsic uniqueness.
-void NeonEmitter::emitIntrinsic(raw_ostream &OS, Record *R,
-                                StringMap<ClassKind> &EmittedMap) {
-  std::string name = R->getValueAsString("Name");
-  std::string Proto = R->getValueAsString("Prototype");
-  std::string Types = R->getValueAsString("Types");
-
-  SmallVector<StringRef, 16> TypeVec;
-  ParseTypes(R, Types, TypeVec);
-
-  OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()];
-
-  ClassKind classKind = ClassNone;
-  if (R->getSuperClasses().size() >= 2)
-    classKind = ClassMap[R->getSuperClasses()[1]];
-  if (classKind == ClassNone && kind == OpNone)
-    PrintFatalError(R->getLoc(), "Builtin has no class kind");
-
-  for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-    if (kind == OpReinterpret) {
-      bool outQuad = false;
-      bool dummy = false;
-      (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy);
-      for (unsigned srcti = 0, srcte = TypeVec.size();
-           srcti != srcte; ++srcti) {
-        bool inQuad = false;
-        (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy);
-        if (srcti == ti || inQuad != outQuad)
-          continue;
-        std::string s = GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[srcti],
-                                     OpCast, ClassS);
-        if (EmittedMap.count(s))
-          continue;
-        EmittedMap[s] = ClassS;
-        OS << s;
-      }
-    } else {
-      std::string s =
-          GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[ti], kind, classKind);
-      if (EmittedMap.count(s)) {
-        errs() << "warning: duplicate definition: " << name
-               << " (type: " << TypeString('d', TypeVec[ti]) << ")\n";
-        continue;
-      }
-      EmittedMap[s] = classKind;
-      OS << s;
-    }
-  }
-  OS << "\n";
-}
-
-static unsigned RangeFromType(const char mod, StringRef typestr) {
-  // base type to get the type string for.
-  bool quad = false, dummy = false;
-  char type = ClassifyType(typestr, quad, dummy, dummy);
-  type = ModType(mod, type, quad, dummy, dummy, dummy, dummy, dummy);
-
-  switch (type) {
-    case 'c':
-      return (8 << (int)quad) - 1;
-    case 'h':
-    case 's':
-      return (4 << (int)quad) - 1;
-    case 'f':
-    case 'i':
-      return (2 << (int)quad) - 1;
-    case 'd':
-    case 'l':
-      return (1 << (int)quad) - 1;
-    case 'k':
-      return 0;
-    default:
-      PrintFatalError("unhandled type!");
-  }
-}
-
-static unsigned RangeScalarShiftImm(const char mod, StringRef typestr) {
-  // base type to get the type string for.
-  bool dummy = false;
-  char type = ClassifyType(typestr, dummy, dummy, dummy);
-  type = ModType(mod, type, dummy, dummy, dummy, dummy, dummy, dummy);
-
-  switch (type) {
-    case 'c':
-      return 7;
-    case 'h':
-    case 's':
-      return 15;
-    case 'f':
-    case 'i':
-      return 31;
-    case 'd':
-    case 'l':
-      return 63;
-    case 'k':
-      return 127;
-    default:
-      PrintFatalError("unhandled type!");
-  }
-}
-
-/// Generate the ARM and AArch64 intrinsic range checking code for
-/// shift/lane immediates, checking for unique declarations.
-void
-NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS) {
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-  StringMap<OpKind> EmittedMap;
-
-  // Generate the intrinsic range checking code for shift/lane immediates.
-  OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n";
-
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-
-    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
-    if (k != OpNone)
-      continue;
-
-    std::string name = R->getValueAsString("Name");
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string Types = R->getValueAsString("Types");
-    std::string Rename = name + "@" + Proto;
-
-    // Functions with 'a' (the splat code) in the type prototype should not get
-    // their own builtin as they use the non-splat variant.
-    if (Proto.find('a') != std::string::npos)
-      continue;
-
-    // Functions which do not have an immediate do not need to have range
-    // checking code emitted.
-    size_t immPos = Proto.find('i');
-    if (immPos == std::string::npos)
-      continue;
-
-    SmallVector<StringRef, 16> TypeVec;
-    ParseTypes(R, Types, TypeVec);
-
-    if (R->getSuperClasses().size() < 2)
-      PrintFatalError(R->getLoc(), "Builtin has no class kind");
-
-    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
-    if (!ProtoHasScalar(Proto))
-      ck = ClassB;
-
-    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      std::string namestr, shiftstr, rangestr;
-
-      if (R->getValueAsBit("isVCVT_N")) {
-        // VCVT between floating- and fixed-point values takes an immediate
-        // in the range [1, 32] for f32, or [1, 64] for f64.
-        ck = ClassB;
-        if (name.find("32") != std::string::npos)
-          rangestr = "l = 1; u = 31"; // upper bound = l + u
-        else if (name.find("64") != std::string::npos)
-          rangestr = "l = 1; u = 63";
-        else
-          PrintFatalError(R->getLoc(),
-              "Fixed point convert name should contains \"32\" or \"64\"");
-
-      } else if (R->getValueAsBit("isScalarShift")) {
-        // Right shifts have an 'r' in the name, left shifts do not.  Convert
-        // instructions have the same bounds and right shifts.
-        if (name.find('r') != std::string::npos ||
-            name.find("cvt") != std::string::npos)
-          rangestr = "l = 1; ";
-
-        unsigned upBound = RangeScalarShiftImm(Proto[immPos - 1], TypeVec[ti]);
-        // Narrow shift has half the upper bound
-        if (R->getValueAsBit("isScalarNarrowShift"))
-          upBound /= 2;
-
-        rangestr += "u = " + utostr(upBound);
-      } else if (R->getValueAsBit("isShift")) {
-        // Builtins which are overloaded by type will need to have their upper
-        // bound computed at Sema time based on the type constant.
-        shiftstr = ", true";
-
-        // Right shifts have an 'r' in the name, left shifts do not.
-        if (name.find('r') != std::string::npos)
-          rangestr = "l = 1; ";
-
-        rangestr += "u = RFT(TV" + shiftstr + ")";
-      } else if (ck == ClassB) {
-        // ClassB intrinsics have a type (and hence lane number) that is only
-        // known at runtime.
-        assert(immPos > 0 && "unexpected immediate operand");
-        if (R->getValueAsBit("isLaneQ"))
-          rangestr = "u = RFT(TV, false, true)";
-        else
-          rangestr = "u = RFT(TV, false, false)";
-      } else {
-        // The immediate generally refers to a lane in the preceding argument.
-        assert(immPos > 0 && "unexpected immediate operand");
-        rangestr =
-            "u = " + utostr(RangeFromType(Proto[immPos - 1], TypeVec[ti]));
-      }
-      // Make sure cases appear only once by uniquing them in a string map.
-      namestr = MangleName(name, TypeVec[ti], ck);
-      if (EmittedMap.count(namestr))
-        continue;
-      EmittedMap[namestr] = OpNone;
-
-      // Calculate the index of the immediate that should be range checked.
-      unsigned immidx = 0;
-
-      // Builtins that return a struct of multiple vectors have an extra
-      // leading arg for the struct return.
-      if (IsMultiVecProto(Proto[0]))
-        ++immidx;
-
-      // Add one to the index for each argument until we reach the immediate
-      // to be checked.  Structs of vectors are passed as multiple arguments.
-      for (unsigned ii = 1, ie = Proto.size(); ii != ie; ++ii) {
-        switch (Proto[ii]) {
-        default:
-          immidx += 1;
-          break;
-        case '2':
-        case 'B':
-          immidx += 2;
-          break;
-        case '3':
-        case 'C':
-          immidx += 3;
-          break;
-        case '4':
-        case 'D':
-          immidx += 4;
-          break;
-        case 'i':
-          ie = ii + 1;
-          break;
-        }
-      }
-      OS << "case NEON::BI__builtin_neon_";
-      OS << MangleName(name, TypeVec[ti], ck) << ": i = " << immidx << "; "
-         << rangestr << "; break;\n";
-    }
-  }
-  OS << "#endif\n\n";
-}
-
-struct OverloadInfo {
-  uint64_t Mask;
-  int PtrArgNum;
-  bool HasConstPtr;
-};
-/// Generate the ARM and AArch64 overloaded type checking code for
-/// SemaChecking.cpp, checking for unique builtin declarations.
-void
-NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS) {
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-
-  // Generate the overloaded type checking code for SemaChecking.cpp
-  OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n";
-
-  // We record each overload check line before emitting because subsequent Inst
-  // definitions may extend the number of permitted types (i.e. augment the
-  // Mask). Use std::map to avoid sorting the table by hash number.
-  std::map<std::string, OverloadInfo> OverloadMap;
-  typedef std::map<std::string, OverloadInfo>::iterator OverloadIterator;
-
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
-    if (k != OpNone)
-      continue;
-
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string Types = R->getValueAsString("Types");
-    std::string name = R->getValueAsString("Name");
-    std::string Rename = name + "@" + Proto;
-
-    // Functions with 'a' (the splat code) in the type prototype should not get
-    // their own builtin as they use the non-splat variant.
-    if (Proto.find('a') != std::string::npos)
-      continue;
-
-    // Functions which have a scalar argument cannot be overloaded, no need to
-    // check them if we are emitting the type checking code.
-    if (ProtoHasScalar(Proto))
-      continue;
-
-    SmallVector<StringRef, 16> TypeVec;
-    ParseTypes(R, Types, TypeVec);
-
-    if (R->getSuperClasses().size() < 2)
-      PrintFatalError(R->getLoc(), "Builtin has no class kind");
-
-    int si = -1, qi = -1;
-    uint64_t mask = 0, qmask = 0;
-    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      // Generate the switch case(s) for this builtin for the type validation.
-      bool quad = false, poly = false, usgn = false;
-      (void) ClassifyType(TypeVec[ti], quad, poly, usgn);
-
-      if (quad) {
-        qi = ti;
-        qmask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);
-      } else {
-        si = ti;
-        mask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);
-      }
-    }
-
-    // Check if the builtin function has a pointer or const pointer argument.
-    int PtrArgNum = -1;
-    bool HasConstPtr = false;
-    for (unsigned arg = 1, arge = Proto.size(); arg != arge; ++arg) {
-      char ArgType = Proto[arg];
-      if (ArgType == 'c') {
-        HasConstPtr = true;
-        PtrArgNum = arg - 1;
-        break;
-      }
-      if (ArgType == 'p') {
-        PtrArgNum = arg - 1;
-        break;
-      }
-    }
-    // For sret builtins, adjust the pointer argument index.
-    if (PtrArgNum >= 0 && IsMultiVecProto(Proto[0]))
-      PtrArgNum += 1;
-
-    // Omit type checking for the pointer arguments of vld1_lane, vld1_dup,
-    // and vst1_lane intrinsics.  Using a pointer to the vector element
-    // type with one of those operations causes codegen to select an aligned
-    // load/store instruction.  If you want an unaligned operation,
-    // the pointer argument needs to have less alignment than element type,
-    // so just accept any pointer type.
-    if (name == "vld1_lane" || name == "vld1_dup" || name == "vst1_lane") {
-      PtrArgNum = -1;
-      HasConstPtr = false;
-    }
-
-    if (mask) {
-      std::pair<OverloadIterator, bool> I = OverloadMap.insert(std::make_pair(
-          MangleName(name, TypeVec[si], ClassB), OverloadInfo()));
-      OverloadInfo &Record = I.first->second;
-      if (!I.second)
-        assert(Record.PtrArgNum == PtrArgNum &&
-               Record.HasConstPtr == HasConstPtr);
-      Record.Mask |= mask;
-      Record.PtrArgNum = PtrArgNum;
-      Record.HasConstPtr = HasConstPtr;
-    }
-    if (qmask) {
-      std::pair<OverloadIterator, bool> I = OverloadMap.insert(std::make_pair(
-          MangleName(name, TypeVec[qi], ClassB), OverloadInfo()));
-      OverloadInfo &Record = I.first->second;
-      if (!I.second)
-        assert(Record.PtrArgNum == PtrArgNum &&
-               Record.HasConstPtr == HasConstPtr);
-      Record.Mask |= qmask;
-      Record.PtrArgNum = PtrArgNum;
-      Record.HasConstPtr = HasConstPtr;
-    }
-  }
-
-  for (OverloadIterator I = OverloadMap.begin(), E = OverloadMap.end(); I != E;
-       ++I) {
-    OverloadInfo &BuiltinOverloads = I->second;
-    OS << "case NEON::BI__builtin_neon_" << I->first << ": ";
-    OS << "mask = " << "0x" << utohexstr(BuiltinOverloads.Mask) << "ULL";
-    if (BuiltinOverloads.PtrArgNum >= 0)
-      OS << "; PtrArgNum = " << BuiltinOverloads.PtrArgNum;
-    if (BuiltinOverloads.HasConstPtr)
-      OS << "; HasConstPtr = true";
-    OS << "; break;\n";
-  }
-
-  OS << "#endif\n\n";
-}
-
-/// genBuiltinsDef: Generate the BuiltinsARM.def and  BuiltinsAArch64.def
-/// declaration of builtins, checking for unique builtin declarations.
-void NeonEmitter::genBuiltinsDef(raw_ostream &OS) {
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-
-  // We want to emit the intrinsics in alphabetical order, so use the more
-  // expensive std::map to gather them together first.
-  std::map<std::string, OpKind> EmittedMap;
-
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
-    if (k != OpNone)
-      continue;
-
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string name = R->getValueAsString("Name");
-    std::string Rename = name + "@" + Proto;
-
-    // Functions with 'a' (the splat code) in the type prototype should not get
-    // their own builtin as they use the non-splat variant.
-    if (Proto.find('a') != std::string::npos)
-      continue;
-
-    std::string Types = R->getValueAsString("Types");
-    SmallVector<StringRef, 16> TypeVec;
-    ParseTypes(R, Types, TypeVec);
-
-    if (R->getSuperClasses().size() < 2)
-      PrintFatalError(R->getLoc(), "Builtin has no class kind");
-
-    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
-
-    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      // Generate the declaration for this builtin, ensuring
-      // that each unique BUILTIN() macro appears only once in the output
-      // stream.
-      std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck);
-      if (EmittedMap.count(bd))
-        continue;
-
-      EmittedMap[bd] = OpNone;
-    }
-  }
-
-  // Generate BuiltinsNEON.
-  OS << "#ifdef GET_NEON_BUILTINS\n";
-
-  for (std::map<std::string, OpKind>::iterator I = EmittedMap.begin(),
-                                               E = EmittedMap.end();
-       I != E; ++I)
-    OS << I->first << "\n";
-
-  OS << "#endif\n\n";
-}
-
-/// runHeader - Emit a file with sections defining:
-/// 1. the NEON section of BuiltinsARM.def and BuiltinsAArch64.def.
-/// 2. the SemaChecking code for the type overload checking.
-/// 3. the SemaChecking code for validation of intrinsic immediate arguments.
-void NeonEmitter::runHeader(raw_ostream &OS) {
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-
-  // Generate shared BuiltinsXXX.def
-  genBuiltinsDef(OS);
-
-  // Generate ARM overloaded type checking code for SemaChecking.cpp
-  genOverloadTypeCheckCode(OS);
-
-  // Generate ARM range checking code for shift/lane immediates.
-  genIntrinsicRangeCheckCode(OS);
-}
-
-/// GenTest - Write out a test for the intrinsic specified by the name and
-/// type strings, including the embedded patterns for FileCheck to match.
-static std::string GenTest(const std::string &name,
-                           const std::string &proto,
-                           StringRef outTypeStr, StringRef inTypeStr,
-                           bool isShift, bool isHiddenLOp,
-                           ClassKind ck, const std::string &InstName,
-                           bool isA64,
-                           std::string & testFuncProto) {
-  assert(!proto.empty() && "");
-  std::string s;
-
-  // Function name with type suffix
-  std::string mangledName = MangleName(name, outTypeStr, ClassS);
-  if (outTypeStr != inTypeStr) {
-    // If the input type is different (e.g., for vreinterpret), append a suffix
-    // for the input type.  String off a "Q" (quad) prefix so that MangleName
-    // does not insert another "q" in the name.
-    unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0);
-    StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff);
-    mangledName = MangleName(mangledName, inTypeNoQuad, ClassS);
-  }
-
-  // todo: GenerateChecksForIntrinsic does not generate CHECK
-  // for aarch64 instructions yet
-  std::vector<std::string> FileCheckPatterns;
-  if (!isA64) {
-    GenerateChecksForIntrinsic(name, proto, outTypeStr, inTypeStr, ck, InstName,
-                               isHiddenLOp, FileCheckPatterns);
-    s+= "// CHECK_ARM: test_" + mangledName + "\n";
-  }
-  s += "// CHECK_AARCH64: test_" + mangledName + "\n";
-
-  // Emit the FileCheck patterns.
-  // If for any reason we do not want to emit a check, mangledInst
-  // will be the empty string.
-  if (FileCheckPatterns.size()) {
-    for (std::vector<std::string>::const_iterator i = FileCheckPatterns.begin(),
-                                                  e = FileCheckPatterns.end();
-         i != e;
-         ++i) {
-      s += "// CHECK_ARM: " + *i + "\n";
-    }
-  }
-
-  // Emit the start of the test function.
-
-  testFuncProto = TypeString(proto[0], outTypeStr) + " test_" + mangledName + "(";
-  char arg = 'a';
-  std::string comma;
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    // Do not create arguments for values that must be immediate constants.
-    if (proto[i] == 'i')
-      continue;
-    testFuncProto += comma + TypeString(proto[i], inTypeStr) + " ";
-    testFuncProto.push_back(arg);
-    comma = ", ";
-  }
-  testFuncProto += ")";
-
-  s+= testFuncProto;
-  s+= " {\n  ";
-
-  if (proto[0] != 'v')
-    s += "return ";
-  s += mangledName + "(";
-  arg = 'a';
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    if (proto[i] == 'i') {
-      // For immediate operands, test the maximum value.
-      if (isShift)
-        s += "1"; // FIXME
-      else
-        // The immediate generally refers to a lane in the preceding argument.
-        s += utostr(RangeFromType(proto[i-1], inTypeStr));
-    } else {
-      s.push_back(arg);
-    }
-    if ((i + 1) < e)
-      s += ", ";
-  }
-  s += ");\n}\n\n";
-  return s;
-}
-
-/// Write out all intrinsic tests for the specified target, checking
-/// for intrinsic test uniqueness.
-void NeonEmitter::genTargetTest(raw_ostream &OS) {
-  StringMap<OpKind> EmittedMap;
-  std::string CurrentGuard = "";
-  bool InGuard = false;
-
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-    std::string name = R->getValueAsString("Name");
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string Types = R->getValueAsString("Types");
-    bool isShift = R->getValueAsBit("isShift");
-    std::string InstName = R->getValueAsString("InstName");
-    bool isHiddenLOp = R->getValueAsBit("isHiddenLInst");
-
-    std::string NewGuard = R->getValueAsString("ArchGuard");
-    if (NewGuard != CurrentGuard) {
-      if (InGuard)
-        OS << "#endif\n\n";
-      if (NewGuard.size())
-        OS << "#if " << NewGuard << '\n';
-
-      CurrentGuard = NewGuard;
-      InGuard = NewGuard.size() != 0;
-    }
-
-    SmallVector<StringRef, 16> TypeVec;
-    ParseTypes(R, Types, TypeVec);
-
-    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
-    OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()];
-    if (kind == OpUnavailable)
-      continue;
-    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      if (kind == OpReinterpret) {
-        bool outQuad = false;
-        bool dummy = false;
-        (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy);
-        for (unsigned srcti = 0, srcte = TypeVec.size();
-             srcti != srcte; ++srcti) {
-          bool inQuad = false;
-          (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy);
-          if (srcti == ti || inQuad != outQuad)
-            continue;
-          std::string testFuncProto;
-          std::string s = GenTest(name, Proto, TypeVec[ti], TypeVec[srcti],
-                                  isShift, isHiddenLOp, ck, InstName,
-                                  CurrentGuard.size(), testFuncProto);
-          if (EmittedMap.count(testFuncProto))
-            continue;
-          EmittedMap[testFuncProto] = kind;
-          OS << s << "\n";
-        }
-      } else {
-        std::string testFuncProto;
-        std::string s =
-            GenTest(name, Proto, TypeVec[ti], TypeVec[ti], isShift, isHiddenLOp,
-                    ck, InstName, CurrentGuard.size(), testFuncProto);
-        OS << s << "\n";
-      }
-    }
-  }
-
-  if (InGuard)
-    OS << "#endif\n";
-}
-/// runTests - Write out a complete set of tests for all of the Neon
-/// intrinsics.
-void NeonEmitter::runTests(raw_ostream &OS) {
-  OS << "// RUN: %clang_cc1 -triple thumbv7s-apple-darwin -target-abi "
-        "apcs-gnu\\\n"
-        "// RUN:  -target-cpu swift -ffreestanding -Os -S -o - %s\\\n"
-        "// RUN:  | FileCheck %s -check-prefix=CHECK_ARM\n"
-        "\n"
-        "// RUN: %clang_cc1 -triple aarch64-none-linux-gnu \\\n"
-        "// RUN -target-feature +neon  -ffreestanding -S -o - %s \\\n"
-        "// RUN:  | FileCheck %s -check-prefix=CHECK_AARCH64\n"
-        "\n"
-        "// REQUIRES: long_tests\n"
-        "\n"
-        "#include <arm_neon.h>\n"
-        "\n";
-
-  genTargetTest(OS);
-}
-
 namespace clang {
 void EmitNeon(RecordKeeper &Records, raw_ostream &OS) {
   NeonEmitter(Records).run(OS);
@@ -3421,6 +2392,6 @@
   NeonEmitter(Records).runHeader(OS);
 }
 void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) {
-  NeonEmitter(Records).runTests(OS);
+  llvm_unreachable("Neon test generation no longer implemented!");
 }
 } // End namespace clang
diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h
index 7e05496..78745f1 100644
--- a/utils/TableGen/TableGenBackends.h
+++ b/utils/TableGen/TableGenBackends.h
@@ -61,6 +61,9 @@
 void EmitNeon(RecordKeeper &Records, raw_ostream &OS);
 void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS);
 void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS);
+void EmitNeon2(RecordKeeper &Records, raw_ostream &OS);
+void EmitNeonSema2(RecordKeeper &Records, raw_ostream &OS);
+void EmitNeonTest2(RecordKeeper &Records, raw_ostream &OS);
 
 void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS);
 
diff --git a/utils/clang.natvis b/utils/clang.natvis
index 1f956f1..107af50 100644
--- a/utils/clang.natvis
+++ b/utils/clang.natvis
@@ -15,14 +15,14 @@
   </Type>

   <Type Name="clang::DeclarationName">

     <DisplayString Condition="Ptr == 0">Empty</DisplayString>

-    <DisplayString Condition="(Ptr &amp; PtrMask) == StoredIdentifier">{{Identifier ({(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>

-    <DisplayString Condition="(Ptr &amp; PtrMask) == StoredObjCZeroArgSelector">{{ObjC Zero Arg Selector ({(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>

-    <DisplayString Condition="(Ptr &amp; PtrMask) == StoredObjCOneArgSelector">{{ObjC One Arg Selector ({(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>

+    <DisplayString Condition="(Ptr &amp; PtrMask) == StoredIdentifier">{{Identifier ({*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>

+    <DisplayString Condition="(Ptr &amp; PtrMask) == StoredObjCZeroArgSelector">{{ObjC Zero Arg Selector (*{(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>

+    <DisplayString Condition="(Ptr &amp; PtrMask) == StoredObjCOneArgSelector">{{ObjC One Arg Selector (*{(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>

     <DisplayString Condition="(Ptr &amp; PtrMask) == StoredDeclarationNameExtra">{{Extra ({(clang::DeclarationNameExtra::ExtraKind)((clang::DeclarationNameExtra *)(Ptr &amp; ~PtrMask))-&gt;ExtraKindOrNumArgs})}}</DisplayString>

     <Expand>

-      <Item Condition="(Ptr &amp; PtrMask) == StoredIdentifier" Name="[Identifier]">(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>

-      <Item Condition="(Ptr &amp; PtrMask) == StoredObjCZeroArgSelector" Name="[ObjC Zero Arg Selector]">(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>

-      <Item Condition="(Ptr &amp; PtrMask) == StoredObjCOneArgSelector" Name="[ObjC One Arg Selector]">(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>

+      <Item Condition="(Ptr &amp; PtrMask) == StoredIdentifier" Name="[Identifier]">*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>

+      <Item Condition="(Ptr &amp; PtrMask) == StoredObjCZeroArgSelector" Name="[ObjC Zero Arg Selector]">*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>

+      <Item Condition="(Ptr &amp; PtrMask) == StoredObjCOneArgSelector" Name="[ObjC One Arg Selector]">*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>

       <Item Condition="(Ptr &amp; PtrMask) == StoredDeclarationNameExtra" Name="[Extra]">(clang::DeclarationNameExtra::ExtraKind)((clang::DeclarationNameExtra *)(Ptr &amp; ~PtrMask))-&gt;ExtraKindOrNumArgs</Item>

     </Expand>

   </Type>

@@ -41,4 +41,19 @@
   <Type Name="clang::DirectoryEntry">

     <DisplayString>{Name,s}</DisplayString>

   </Type>

+  <Type Name="clang::VarDecl::VarDeclBitfields">

+    <Expand>

+      <Item Name="StorageClass">(clang::StorageClass)SClass</Item>

+      <Item Name="ThreadStorageClass">(clang::ThreadStorageClassSpecifier)TSCSpec</Item>

+      <Item Name="InitStyle">(clang::VarDecl::InitializationStyle)InitStyle</Item>

+    </Expand>

+  </Type>

+  <Type Name="clang::VarDecl">

+    <DisplayString>{Name}</DisplayString>

+    <Expand>

+      <ExpandedItem>*(DeclaratorDecl*)this,nd</ExpandedItem>

+      <Item Name="VarDeclBits">VarDeclBits</Item>

+      <Item Name="ParmVarDeclBits">ParmVarDeclBits</Item>

+    </Expand>

+  </Type>

 </AutoVisualizer>

diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html
index 7979013..6d27d00 100644
--- a/www/cxx_dr_status.html
+++ b/www/cxx_dr_status.html
@@ -3233,7 +3233,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#532">532</a></td>
     <td>C++11</td>
     <td>Member/nonmember operator template partial ordering</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="533">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#533">533</a></td>
@@ -5755,7 +5755,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#990">990</a></td>
     <td>CD2</td>
     <td>Value initialization with multiple initializer-list constructors</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="991">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#991">991</a></td>
@@ -6235,7 +6235,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1070">1070</a></td>
     <td>C++11</td>
     <td>Missing initializer clauses in aggregate initialization</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="1071">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1071">1071</a></td>
@@ -7761,11 +7761,11 @@
     <td>Value initialization and defaulted constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="1325">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1325">1325</a></td>
-    <td>drafting</td>
+  <tr id="1325">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1325">1325</a></td>
+    <td>NAD</td>
     <td>Omitted declarator in <TT>friend</TT> declarations</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="1326">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1326">1326</a></td>
@@ -7917,11 +7917,11 @@
     <td>Incorrect exception specification for inherited constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr id="1351">
+  <tr class="open" id="1351">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1351">1351</a></td>
-    <td>ready</td>
+    <td>review</td>
     <td>Problems with implicitly-declared <I>exception-specification</I>s</td>
-    <td class="none" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr id="1352">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1352">1352</a></td>
@@ -7947,11 +7947,11 @@
     <td>Aggregates and &#8220;user-provided&#8221; constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr id="1356">
+  <tr class="open" id="1356">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1356">1356</a></td>
-    <td>ready</td>
+    <td>review</td>
     <td>Exception specifications of copy assignment operators with virtual bases</td>
-    <td class="none" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr id="1357">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1357">1357</a></td>
@@ -8193,11 +8193,11 @@
     <td>Deferred instantiation and checking of non-static data member initializers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open" id="1397">
+  <tr id="1397">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1397">1397</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Class completeness in non-static data member initializers</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="1398">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1398">1398</a></td>
@@ -8601,11 +8601,11 @@
     <td>Negative array bound in a <I>new-expression</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr id="1465">
+  <tr class="open" id="1465">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1465">1465</a></td>
-    <td>ready</td>
+    <td>review</td>
     <td><TT>noexcept</TT> and <TT>std::bad_array_new_length</TT></td>
-    <td class="none" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr id="1466">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1466">1466</a></td>
@@ -9351,11 +9351,11 @@
     <td>Ambiguous ranking of list-initialization sequences</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr id="1590">
+  <tr class="open" id="1590">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1590">1590</a></td>
-    <td>ready</td>
+    <td>review</td>
     <td>Bypassing non-copy/move constructor copying</td>
-    <td class="none" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr id="1591">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1591">1591</a></td>
@@ -9645,11 +9645,11 @@
     <td>Declaring an explicit specialization of a scoped enumeration</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr id="1639">
+  <tr class="open" id="1639">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1639">1639</a></td>
-    <td>ready</td>
+    <td>review</td>
     <td><I>exception-specification</I>s and pointer/pointer-to-member expressions</td>
-    <td class="none" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="1640">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1640">1640</a></td>
@@ -10059,11 +10059,11 @@
     <td><TT>template</TT> in <I>elaborated-type-specifier</I> without <I>nested-name-specifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr id="1708">
+  <tr class="open" id="1708">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1708">1708</a></td>
-    <td>ready</td>
+    <td>review</td>
     <td>overly-strict requirements for names with C language linkage</td>
-    <td class="none" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="1709">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1709">1709</a></td>
@@ -10671,11 +10671,11 @@
     <td>Narrowing and template argument deduction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr id="1810">
+  <tr class="open" id="1810">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1810">1810</a></td>
-    <td>ready</td>
+    <td>review</td>
     <td>Invalid <I>ud-suffix</I>es</td>
-    <td class="none" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr id="1811">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1811">1811</a></td>
@@ -11007,6 +11007,402 @@
     <td>Pointer arithmetic and multi-level qualification conversions</td>
     <td align="center">Not resolved</td>
   </tr>
+  <tr class="open" id="1866">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1866">1866</a></td>
+    <td>open</td>
+    <td>Initializing variant members with non-trivial destructors</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1867">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1867">1867</a></td>
+    <td>open</td>
+    <td>Function/expression ambiguity with qualified parameter name</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1868">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1868">1868</a></td>
+    <td>open</td>
+    <td>Meaning of &#8220;placeholder type&#8221;</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1869">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1869">1869</a></td>
+    <td>open</td>
+    <td><TT>thread_local</TT> vs <I>linkage-specification</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1870">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1870">1870</a></td>
+    <td>open</td>
+    <td>Contradictory wording about definitions vs explicit specialization/instantiation</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1871">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1871">1871</a></td>
+    <td>open</td>
+    <td>Non-identifier characters in <I>ud-suffix</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1872">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1872">1872</a></td>
+    <td>open</td>
+    <td>Instantiations of <TT>constexpr</TT> templates that cannot appear in constant expressions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1873">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1873">1873</a></td>
+    <td>open</td>
+    <td>Protected member access from derived class friends</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1874">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1874">1874</a></td>
+    <td>open</td>
+    <td>Type vs non-type template parameters with <TT>class</TT> keyword</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1875">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1875">1875</a></td>
+    <td>open</td>
+    <td>Reordering declarations in class scope</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1876">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1876">1876</a></td>
+    <td>open</td>
+    <td>Preventing explicit specialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1877">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1877">1877</a></td>
+    <td>open</td>
+    <td>Return type deduction from <TT>return</TT> with no operand</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1878">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1878">1878</a></td>
+    <td>open</td>
+    <td><TT>operator auto</TT> template</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1879">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1879">1879</a></td>
+    <td>open</td>
+    <td>Inadequate definition of alignment requirement</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1880">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1880">1880</a></td>
+    <td>open</td>
+    <td>When are parameter objects destroyed?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1881">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1881">1881</a></td>
+    <td>open</td>
+    <td>Standard-layout classes and unnamed bit-fields</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1882">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1882">1882</a></td>
+    <td>open</td>
+    <td>Reserved names without library use</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1883">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1883">1883</a></td>
+    <td>open</td>
+    <td>Protected access to constructors in <I>mem-initializer</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1884">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1884">1884</a></td>
+    <td>open</td>
+    <td>Unclear requirements for same-named external-linkage entities</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1885">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1885">1885</a></td>
+    <td>open</td>
+    <td>Return value of a function is underspecified</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1886">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1886">1886</a></td>
+    <td>open</td>
+    <td>Language linkage for <TT>main()</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1887">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1887">1887</a></td>
+    <td>open</td>
+    <td>Problems with <TT>::</TT> as <I>nested-name-specifier</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1888">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1888">1888</a></td>
+    <td>open</td>
+    <td>Implicitly-declared default constructors and <TT>explicit</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1889">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1889">1889</a></td>
+    <td>open</td>
+    <td>Unclear effect of <TT>#pragma</TT> on conformance</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1890">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1890">1890</a></td>
+    <td>open</td>
+    <td>Member type depending on definition of member function</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1891">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1891">1891</a></td>
+    <td>open</td>
+    <td>Move constructor/assignment for closure class</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1892">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1892">1892</a></td>
+    <td>open</td>
+    <td>Use of <TT>auto</TT> in function type</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1893">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1893">1893</a></td>
+    <td>open</td>
+    <td>Function-syle cast with <I>braced-init-list</I>s and empty pack expansions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1894">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1894">1894</a></td>
+    <td>open</td>
+    <td><I>typedef-name</I>s and <I>using-declaration</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1895">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1895">1895</a></td>
+    <td>open</td>
+    <td>Deleted conversions in conditional operator operands</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1896">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1896">1896</a></td>
+    <td>open</td>
+    <td>Repeated alias templates</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1897">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1897">1897</a></td>
+    <td>open</td>
+    <td>ODR vs alternative tokens</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1898">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1898">1898</a></td>
+    <td>open</td>
+    <td>Use of &#8220;equivalent&#8221; in overload resolution</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1899">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1899">1899</a></td>
+    <td>open</td>
+    <td>Value-dependent constant expressions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1900">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1900">1900</a></td>
+    <td>open</td>
+    <td>Do <TT>friend</TT> declarations count as &#8220;previous declarations&#8221;?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1901">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1901">1901</a></td>
+    <td>open</td>
+    <td><I>punctuator</I> referenced but not defined</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1902">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1902">1902</a></td>
+    <td>open</td>
+    <td>What makes a conversion &#8220;otherwise ill-formed&#8221;?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1903">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1903">1903</a></td>
+    <td>open</td>
+    <td>What declarations are introduced by a non-member <I>using-declaration</I>?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1904">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1904">1904</a></td>
+    <td>open</td>
+    <td>Default template arguments for members of class templates</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1905">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1905">1905</a></td>
+    <td>open</td>
+    <td>Dependent types and injected-class-names</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1906">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1906">1906</a></td>
+    <td>open</td>
+    <td>Name lookup in member <TT>friend</TT> declaration</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1907">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1907">1907</a></td>
+    <td>open</td>
+    <td><I>using-declaration</I>s and default arguments</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1908">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1908">1908</a></td>
+    <td>open</td>
+    <td>Dual destructor lookup and <I>template-id</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1909">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1909">1909</a></td>
+    <td>open</td>
+    <td>Member class template with the same name as the class</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1910">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1910">1910</a></td>
+    <td>open</td>
+    <td>&#8220;Shall&#8221; requirement applied to runtime behavior</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1911">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1911">1911</a></td>
+    <td>open</td>
+    <td><TT>constexpr</TT> constructor with non-literal base class</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1912">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1912">1912</a></td>
+    <td>open</td>
+    <td><I>exception-specification</I> of defaulted function</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1913">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1913">1913</a></td>
+    <td>open</td>
+    <td><TT>decltype((x))</TT> in <I>lambda-expression</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1914">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1914">1914</a></td>
+    <td>open</td>
+    <td>Duplicate standard attributes</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1915">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1915">1915</a></td>
+    <td>open</td>
+    <td>Potentially-invoked destructors in non-throwing constructors</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1916">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1916">1916</a></td>
+    <td>open</td>
+    <td>&#8220;Same cv-unqualified type&#8221;</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1917">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1917">1917</a></td>
+    <td>open</td>
+    <td>decltype-qualified enumeration names</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1918">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1918">1918</a></td>
+    <td>open</td>
+    <td><TT>friend</TT> templates with dependent scopes</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1919">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1919">1919</a></td>
+    <td>open</td>
+    <td>Overload resolution for <TT>!</TT> with explicit conversion operator</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1920">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1920">1920</a></td>
+    <td>open</td>
+    <td>Qualification mismatch in <I>pseudo-destructor-name</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1921">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1921">1921</a></td>
+    <td>open</td>
+    <td><TT>constexpr</TT> constructors and point of initialization of <TT>const</TT> variables</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1922">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1922">1922</a></td>
+    <td>open</td>
+    <td>Injected class template names and default arguments</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1923">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1923">1923</a></td>
+    <td>open</td>
+    <td>Lvalues of type <TT>void</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1924">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1924">1924</a></td>
+    <td>open</td>
+    <td>Definition of &#8220;literal&#8221; and kinds of literals</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1925">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1925">1925</a></td>
+    <td>open</td>
+    <td>Bit-field prvalues</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1926">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1926">1926</a></td>
+    <td>open</td>
+    <td>Potential results of subscript operator</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1927">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1927">1927</a></td>
+    <td>open</td>
+    <td>Lifetime of temporaries in <I>init-capture</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1928">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1928">1928</a></td>
+    <td>open</td>
+    <td>Triviality of deleted special member functions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1929">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1929">1929</a></td>
+    <td>open</td>
+    <td><TT>template</TT> keyword following namespace <I>nested-name-specifier</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1930">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1930">1930</a></td>
+    <td>open</td>
+    <td><I>init-declarator-list</I> vs <I>member-declarator-list</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1931">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1931">1931</a></td>
+    <td>open</td>
+    <td>Default-constructible and copy-assignable closure types</td>
+    <td align="center">Not resolved</td>
+  </tr>
 </table>
 
 </div>
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 0849bbc..f2ab072 100644
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -3,7 +3,7 @@
 <html>
 <head>
   <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-  <title>Clang - C++14, C++11 and C++98 Status</title>
+  <title>Clang - C++1z, C++14, C++11 and C++98 Status</title>
   <link type="text/css" rel="stylesheet" href="menu.css">
   <link type="text/css" rel="stylesheet" href="content.css">
   <style type="text/css">
@@ -23,13 +23,15 @@
 <div id="content">
 
 <!--*************************************************************************-->
-<h1>C++14, C++11 and C++98 Support in Clang</h1>
+<h1>C++ Support in Clang</h1>
 <!--*************************************************************************-->
 <p>Last updated: $Date$</p>
 
 <p>Clang fully implements all published ISO C++ standards including <a
 href="#cxx11">C++11</a>, as well as the upcoming standard provisionally named <a
-href="#cxx14">C++14</a>, and is considered a production-quality C++ compiler.
+href="#cxx14">C++14</a>, and some parts of the fledgling <a
+href="#cxx17">C++1z</a> standard,
+and is considered a production-quality C++ compiler.
 
 <p>The Clang community is continually striving to improve C++ standards
 compliance between releases by submitting and tracking <a
@@ -48,11 +50,11 @@
 
 <p>Clang implements all of the ISO C++ 1998 standard
   (including the defects addressed in the ISO C++ 2003 standard)
-  except for <tt>export</tt> (which has been removed in C++11).
+  except for <tt>export</tt> (which was removed in C++11).
 
 <h2 id="cxx11">C++11 implementation status</h2>
 
-  <p>Clang implements all of the <a
+  <p>Clang 3.3 and later implement all of the <a
     href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372">ISO
     C++ 2011 standard</a>. The following table describes the Clang version
   in which each feature became available.</p>
@@ -422,8 +424,9 @@
 
 <h2 id="cxx14">C++1y implementation status</h2>
 
-<p>Clang implements all of the
-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf">current draft</a>
+<p>Clang 3.4 and later implement all of the Draft International Standard (see <a
+href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf">most
+recent publicly available draft</a>)
 of the upcoming C++ language standard, provisionally named C++1y.  The following
 table describes the Clang version in which each feature became available.</p>
 
@@ -501,16 +504,46 @@
     </tr>
 </table>
 
-<!--
 <h2 id="cxx17">C++1z implementation status</h2>
 
-<p>Clang implements none of the upcoming C++ language standard,
+<p>Clang has <b>highly experimental</b> support for some proposed features of
+the C++ standard following C++1y,
 provisionally named C++1z.  The following table describes which C++1z features
 have been implemented in Clang and in which Clang version they became
 available.</p>
 
+<p>Note that support for these features may change or be removed without notice,
+as the draft C++1z standard evolves.</p>
+
 <p>You can use Clang in C++1z mode with the <code>-std=c++1z</code> option.</p>
--->
+
+<table width="689" border="1" cellspacing="0">
+ <tr>
+    <th>Language Feature</th>
+    <th>C++1z Proposal</th>
+    <th>Available in Clang?</th>
+ </tr>
+    <tr>
+      <td><tt>static_assert</tt> with no message</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3928.pdf">N3928</a></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
+    <tr>
+      <td>Disabling trigraph expansion by default</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3981.html">N3981</a></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
+    <tr>
+      <td>Terse range-based for loops</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3994.htm">N3994</a></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
+    <tr>
+      <td><tt>typename</tt> in a template template parameter</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4051.html">N4051</a></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
+</table>
 
 <h2 id="ts">Technical specifications and standing documents</h2>
 
diff --git a/www/get_involved.html b/www/get_involved.html
index 5d16db9..06fee59 100644
--- a/www/get_involved.html
+++ b/www/get_involved.html
@@ -21,6 +21,11 @@
 the development of the project to see it progress.
 </p>
 
+<h2>Contribute</h2>
+
+See the <a href="hacking.html">hacking</a> document for information on how
+to author patches.
+
 <h2>Follow what's going on</h2>
 
 <p>Clang is a subproject of the <a href="http://llvm.org">LLVM Project</a>, but
diff --git a/www/hacking.html b/www/hacking.html
index d7a8701..4535ef4 100644
--- a/www/hacking.html
+++ b/www/hacking.html
@@ -111,9 +111,6 @@
   <h2 id="testing">Testing</h2>
   <!--=====================================================================-->
 
-  <p><i>[Note: The test running mechanism is currently under revision, so the
-  following might change shortly.]</i></p>
-
   <!--=====================================================================-->
   <h3 id="testingNonWindows">Testing on Unix-like Systems</h3>
   <!--=====================================================================-->
@@ -279,9 +276,10 @@
   <p>To return changes to the Clang team, unless you have checkin
   privileges, the preferred way is to send patch files to the
   cfe-commits mailing list, with an explanation of what the patch is
-  for.  If your patch requires a wider discussion (for example,
-  because it is an architectural change), you can use the cfe-dev
-  mailing list.  </p>
+  for.  clang follows <a
+  href="http://llvm.org/docs/DeveloperPolicy.html">LLVM's developer policy</a>.
+  If your patch requires a wider discussion (for example, because it is an
+  architectural change), you can use the cfe-dev mailing list.</p>
 
   <p>To create these patch files, change directory
   to the llvm/tools/clang root and run:</p>